首頁  >  文章  >  web前端  >  vue組件怎麼傳值

vue組件怎麼傳值

青灯夜游
青灯夜游原創
2023-01-06 17:26:162401瀏覽

傳值方法:1、利用props實作父傳子;2、子傳父,需要自訂事件,在子元件中以「this.$emit('事件名稱')」觸發,而父中以「@事件名」監聽;3、兄弟間,透過公有父元素作為橋接,結合父子props傳參、子父自訂事件;4、用路由傳值;5、用$ref傳值;6 、以依賴注入傳給後代子孫曾孫;7、利用$attrs;8、藉助$listeners中間事件;9、用$parent傳等。

vue組件怎麼傳值

本教學操作環境:windows7系統、vue3版,DELL G3電腦。

這篇文章帶大家聊聊vue元件傳值的10種方式,常用的也有五六種,先上一張總結圖:

vue組件怎麼傳值

1、父元件傳給子元件

在子元件裡定義一個props,即props:['msg'],msg可以是物件也可以是基本資料型別

如果你想定義一個預設值,也就是props:{msg: {type: String, default: 'hello world'}},
若預設值是物件類型:props: { msg: { type: Object, default: () => { return { name: 'dan_seek' } } }}

#需要注意的是這種傳值是單向的,你無法改變父元件的值(當然引用型別例外);而且如果直接修改props的值會報一個警告。

建議的寫法是在data()裡重新定義一個變數(見Children.vue),並且把props賦值給它,當然計算屬性也行。

Children.vue

<template>
    <section>
        父组件传过来的消息是:{{myMsg}}
    </section>
</template>

<script>
    export default {
        name: "Children",
        components: {},
        props:[&#39;msg&#39;],
        data() {
            return {
                myMsg:this.msg
            }
        },
        methods: {}
    }
</script>

Parent.vue

<template>
  <div class="parent">
    <Children :msg="message"></Children>
  </div>
</template>

<script>
import Children from &#39;../components/Children&#39;

export default {
  name: &#39;Parent&#39;,
  components: {
      Children
  },
  data() {
      return {
          message:&#39;hello world&#39;
}
},
}
</script>

2、子元件傳給父元件

#這裡需要使用自訂事件,在子元件中使用this.$emit('myEvent') 觸發,然後在父元件中使用@myEvent監聽

Children.vue

<template>
    <div class="parent">
        这里是计数:{{parentNum}}
        <Children-Com @addNum="getNum"></Children-Com>
    </div>
</template>

<script>
    import ChildrenCom from &#39;../components/Children&#39;

    export default {
        name: &#39;Parent&#39;,
        components: {
            ChildrenCom
        },
        data() {
            return {
                parentNum: 0
            }
        },
        methods:{
            // childNum是由子组件传入的
            getNum(childNum){
                this.parentNum = childNum
            }
        }
    }
</script>

Parent.vue

<template>
    <div>
        这里是计数:{{parentNum}}
        <children-com></children-com>
    </div></template><script>
    import ChildrenCom from &#39;../components/Children&#39;

    export default {
        name: &#39;Parent&#39;,
        components: {
            ChildrenCom        },
        data() {
            return {
                parentNum: 0
            }
        },
        methods:{
            // childNum是由子组件传入的
            getNum(childNum){
                this.parentNum = childNum            }
        }
    }</script>

3、兄弟元件間傳值

運用自訂事件emit的觸發和監聽能力,定義一個公共的事件匯流排eventBus,透過它作為中間橋樑,我們就可以傳值給任意元件了。而且透過eventBus的使用,可以加深emit的理解。

EventBus.js

import Vue from &#39;vue&#39;
export default new Vue()

Children1.vue

<template>
    <section>
        <div @click="pushMsg">push message</div>
        <br>
    </section>
</template>

<script>
    import eventBus from &#39;./EventBus&#39;
    export default {
        name: "Children1",
        components: {},
        data() {
            return {
                childNum:0
            }
        },
        methods: {
            pushMsg(){
            	// 通过事件总线发送消息
                eventBus.$emit(&#39;pushMsg&#39;,this.childNum++)
            }
        }
    }
</script>

Children2.vue

<template>
    <section>
        children1传过来的消息:{{msg}}
    </section>
</template>

<script>
    import eventBus from &#39;./EventBus&#39;

    export default {
        name: "Children2",
        components: {},
        data() {
            return {
                msg: &#39;&#39;
            }
        },
        mounted() {
        	// 通过事件总线监听消息
            eventBus.$on(&#39;pushMsg&#39;, (children1Msg) => {
                this.msg = children1Msg
            })
        }
    }
</script>

Parent.vue

<template>
    <div class="parent">
        <Children1></Children1>
        <Children2></Children2>
    </div>
</template>

<script>
    import Children1 from &#39;../components/Children1&#39;
    import Children2 from &#39;../components/Children2&#39;

    export default {
        name: &#39;Parent&#39;,
        components: {
            Children1,
            Children2
        },
        data() {
            return {
            }
        },
        methods:{
        }
    }
</script>

github上還有一個開源vue-bus庫,可以參考下: https://github.com/yangmingshan/vue-bus#readme

4、路由間傳值

i.使用問號傳值

A頁面跳轉B頁面時使用this.$router.push('/B?name =danseek')

B頁面可以使用this.$route.query.name 來取得A頁面傳過來的值

#上面要注意router和route的區別

#ii.使用冒號傳值

配置以下路由:

{
    path: &#39;/b/:name&#39;,
    name: &#39;b&#39;,
    component: () => import( &#39;../views/B.vue&#39;)
  },

在B頁面可以透過this.$route.params.name 來取得路由傳入的name的值

iii.使用父子元件傳值

由於router-view本身也是元件,所以我們也可以使用父子元件傳值方式傳值,然後在對應的子頁面裡加上props,因為type更新後沒有刷新路由,所以不能直接在子頁的mounted鉤子裡直接取得最新type的值,而要使用watch。

<router-view></router-view>
// 子页面
......
props: [&#39;type&#39;]
......
watch: {
            type(){
                // console.log("在这个方法可以时刻获取最新的数据:type=",this.type)
            },
        },

5、使用$ref傳值

透過$ref的能力,給子元件定義一個ID,父元件透過這個ID可以直接存取子元件裡面的方法與屬性

先定義一個子元件Children.vue

<template>
    <section>
        传过来的消息:{{msg}}
    </section>
</template>

<script>
    export default {
        name: "Children",
        components: {},
        data() {
            return {
                msg: &#39;&#39;,
                desc:&#39;The use of ref&#39;
            }
        },
        methods:{
            // 父组件可以调用这个方法传入msg
            updateMsg(msg){
                this.msg = msg
            }
        },
    }
</script>

然後在父元件Parent.vue中引用Children.vue,並定義ref屬性

<template>
    <div class="parent">
        <!-- 给子组件设置一个ID ref="children" -->
        <Children ref="children"></Children>
        <div @click="pushMsg">push message</div>
    </div>
</template>

<script>
    import Children from &#39;../components/Children&#39;

    export default {
        name: &#39;parent&#39;,
        components: {
            Children,
        },
        methods:{
            pushMsg(){
                // 通过这个ID可以访问子组件的方法
                this.$refs.children.updateMsg(&#39;Have you received the clothes?&#39;)
                // 也可以访问子组件的属性
                console.log(&#39;children props:&#39;,this.$refs.children.desc)
            }
        },
    }
</script>

6、使用依賴注入傳給後代子孫曾孫

假設父元件有一個方法getName(),需要把它提供給所有的後代

provide: function () {
  return {
    getName: this.getName()
  }
}

provide 選項允許我們指定我們想要提供給後代元件的資料/方法

然後在任何後代元件裡,我們都可以使用inject 來為目前實例注入父元件的資料/方法:

inject: [&#39;getName&#39;]

Parent.vue

<template>
    <div class="parent">
        <Children></Children>
    </div>
</template>

<script>
    import Children from &#39;../components/Children&#39;

    export default {
        name: &#39;Parent&#39;,
        components: {
            Children,
        },
        data() {
            return {
                name:&#39;dan_seek&#39;
            }
        },
        provide: function () {
            return {
                getName: this.name
            }
        },
    }
</script>

Children.vue



<script>
    export default {
        name: "Children",
        components: {},
        data() {
            return {
            }
        },
        inject: [&amp;#39;getName&amp;#39;],
    }
</script>

7、祖傳孫$attrs

正常情況下需要藉助父親的props作為中間過渡,但是這樣在父親組件就會多了一些跟父組件業務無關的屬性,耦合度高,借助$attrs可以簡化些,而且祖跟孫都不需要做修改

GrandParent.vue

<template>
    <section>
        <parent name="grandParent" sex="男" age="88" hobby="code" @sayKnow="sayKnow"></parent>
    </section>
</template>

<script>
    import Parent from &#39;./Parent&#39;
    export default {
        name: "GrandParent",
        components: {
          Parent
        },
        data() {
            return {}
        },
        methods: {
          sayKnow(val){
            console.log(val)
          }
        },
        mounted() {
        }
    }
</script>

Parent.vue

<template>
  <section>
    <p>父组件收到</p>
    <p>祖父的名字:{{name}}</p>
    <children v-bind="$attrs" v-on="$listeners"></children>
  </section>
</template>

<script>
  import Children from &#39;./Children&#39;

  export default {
    name: "Parent",
    components: {
      Children
    },
    // 父组件接收了name,所以name值是不会传到子组件的
    props:[&#39;name&#39;],
    data() {
      return {}
    },
    methods: {},
    mounted() {
    }
  }
</script>

Children.vue

<template>
  <section>
    <p>子组件收到</p>
    <p>祖父的名字:{{name}}</p>
    <p>祖父的性别:{{sex}}</p>
    <p>祖父的年龄:{{age}}</p>
    <p>祖父的爱好:{{hobby}}</p>

    <button @click="sayKnow">我知道啦</button>
  </section>
</template>

<script>
  export default {
    name: "Children",
    components: {},
    // 由于父组件已经接收了name属性,所以name不会传到子组件了
    props:[&#39;sex&#39;,&#39;age&#39;,&#39;hobby&#39;,&#39;name&#39;],
    data() {
      return {}
    },
    methods: {
      sayKnow(){
        this.$emit(&#39;sayKnow&#39;,&#39;我知道啦&#39;)
      }
    },
    mounted() {
    }
  }
</script>
#顯示結果
父组件收到
祖父的名字:grandParent
子组件收到
祖父的名字:
祖父的性别:男
祖父的年龄:88
祖父的爱好:code

8、孫傳祖

借助$listeners中間事件,孫可以方便的通知祖,程式碼範例見7

########################################################################## ########9、$parent#########透過parent可以取得父元件實例,然後透過這個實例就可以存取父元件的屬性和方法,它還有一個兄弟root,可以取得根組件實例。 ###

语法:

// 获父组件的数据
this.$parent.foo

// 写入父组件的数据
this.$parent.foo = 2

// 访问父组件的计算属性
this.$parent.bar

// 调用父组件的方法
this.$parent.baz()

于是,在子组件传给父组件例子中,可以使用this.$parent.getNum(100)传值给父组件。

10、sessionStorage传值

sessionStorage 是浏览器的全局对象,存在它里面的数据会在页面关闭时清除 。运用这个特性,我们可以在所有页面共享一份数据。

语法:

// 保存数据到 sessionStorage
sessionStorage.setItem(&#39;key&#39;, &#39;value&#39;);

// 从 sessionStorage 获取数据
let data = sessionStorage.getItem(&#39;key&#39;);

// 从 sessionStorage 删除保存的数据
sessionStorage.removeItem(&#39;key&#39;);

// 从 sessionStorage 删除所有保存的数据
sessionStorage.clear();

注意:里面存的是键值对,只能是字符串类型,如果要存对象的话,需要使用 let objStr = JSON.stringify(obj) 转成字符串然后再存储(使用的时候 let obj = JSON.parse(objStr) 解析为对象)。

这样存对象是不是很麻烦呢,推荐一个库 good-storage ,它封装了sessionStorage ,可以直接用它的API存对象

// localStorage
 storage.set(key,val) 
 storage.get(key, def)
 
 // sessionStorage
 storage.session.set(key, val)
 storage.session.get(key, val)

更多请移步:https://github.com/ustbhuangyi/storage#readme

【相关推荐:vuejs视频教程web前端开发

以上是vue組件怎麼傳值的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn