vue组件之间的通信

109 阅读1分钟

父 ==> 子

父组件传递数据给子组件,通过自定义属性进行传值,在子组件中自定义属性和使用自定义属性,父组件只负责绑定子组件并进行传值

<!-- 父组件 Father.vue  -->

<template>
    <div>
        <!-- 父组件通过自定义属性向子组件传递数据 -->
       <Son :msg="message" :user="userinfo"></Son> 
    </div>
</template>

<script>
    import Son from "@/components/Son.vue"
    export default{
        data(){
            return{
                message:"这是父组件中的message数据",
                userinfo: {
                    name:"zs",
                    age:18
                }
            }
        },
        components:{
            Son
        }
    }
</script>
<!-- 子组件 Son.vue  -->

<template>
    <div>
        <p>父组件中传递过来的 msg 值为:{{ msg }}</p>
        <p>父组件中传递过来的 user 值为:{{ user }}</p>
    </div>
</template>

<script>
    export default{
        // 子组件中通过 props 节点接收父组件中传递过来的数据
        /* 在 props 节点中的数据的注意点:
            1、props中的数据 和 data 中的数据一样,可以直接在模版结构中访问
            2、在实例中也可以使用 this 关键字访问到props中的数据,如this.user
            3、props 是只读的,不能直接修改 props 中的数据。如果想要修改 props 的值,可以把 props 的值 转存 到 data数据源 中,在数据源中进行修改
        */
        props:["msg","user"]
    }
</script>

子 ==> 父

子组件向父组件共享数据使用自定义事件---this.$emit("自定义事件名称",要发送给父组件的数据)

  • 在子组件中。通过自定义事件 this.$emit("自定义事件名称",要传递的数据) 方法将数据共享给父组件。

  • 父组件中。通过 @自定义事件名称="callback" 绑定自定义事件,在 callback(data) 回调函数中能拿到子组件传递过来的数据

<!-- 子组件 Son.vue  -->

<template>
    <div>
        <p> Son.vue子组件--{{ count }} </p>
        <button @click="add">+1</button>
    </div>
</template>

<script>
    export default{
        data(){
            return{
                // 传递给父组件的数据
                count: 0
            }
        },
        methods:{
          // 每当点击 +1 按钮,让 count 值 +1 后,并将count最新的值传递给父组件
            add(){
                // 让 count 值自增加一
                this.count++
                // 自定义事件 -----  this.$emit("自定义事件名称",要发送给父组件的数据)  
                this.$emit("numChange",this.count)
            }
        },
    }
</script>
<!-- 父组件 Father.vue  -->

<template>
    <div>
       <!-- 监听自定义事件 @自定义事件名称="事件处理函数" -->
       <Son @numChange="getNewCount"></Son>
       <p>count最新的值为:{{ countFromCount }}</p>
    </div>
</template>

<script>
    import Son from "@/components/Son.vue"
    
    export default{
        data(){
            return{
                // 用于接收子组件传递过来的数据
                countFromCount: 0
            }
        },
        methods:{
            // 在事件处理函数中就能拿到子组件传递给父组件的数据
            getNewCount(val){
                // 将数据转存到数据源中
                this.countFromCount = val
            }
        }
        components:{
            Son
        }
    }
</script>

兄 <==> 弟

vue2.x 中,兄弟之间的数据共享方案是 EventBus

/* 创建 eventBus.js  模块 对外共享一个 Vue 实例对象 用于传输数据的中间枢纽 */

import Vue from 'vue'
export default new Vue()
<!-- 数据发送方 Test1.vue 导入 eventBus.js 模块,然后调用`bus.$emit("事件名称",要发送的数据)`方法触发自定义事件 -->

<template>
    <div>
        <button @click="sendMsg">共享数据</button>
    </div>
</template>

<script>
    // 导入 eventBus.js 模块
    import bus from "./eventBus.js"
    
    export default{
        data(){
            return {
                // 定义需要共享的数据
                msg: "Hello brother"
            }
        },
        methods:{
            sendMsg(){
                // 数据的发送方调用 bus.$emit('自定义事件名称','要发送的数据') 方法
                bus.$emit("share", this.msg)
            }
        }
    }
</script>
<!-- 数据接收方 Test2.vue 导入 eventBus.js 模块,调用 `bus.$on("事件名称",事件处理函数)` 方法注册自定义事件 -->

<template>
    <div>
        <p>Test1.vue组件传递过来的数据是:{{ msgFromTest1 }}</p>
    </div>
</template>

<script>
    // 导入 eventBus.js 模块
    import bus from "./eventBus.js"
    
    export default{
        data(){
            return {
                // 用于接收 兄弟组件 传递过来的数据
                msgFromTest1: ""
            }
        },
        // created 生命周期函数
        created(){
            // 接收方调用 bus.$on('自定义事件名称', callback()) 方法,在callback回调函数中可以拿到数据
            bus.$on("share", function(val){
                // 将数据转存在 data 数据源中
                this.msgFromTest1 = val
            })
        }
    }
</script>

祖 ==> 孙

<!-- Gar.vue  爷组件 ---- 共享数据使用 provide 方法 -->

<script>
    export default{
        data(){
          return{
            msg: "这是爷组件中的是数据"
          }
        },
        // 定义 provide 方法对 孙组件 共享数据
        provide(){
            // return 对象中就是传递出去出去的数据
            return {
               // msg: this.mag  单纯键值对的方式传递的数据不具有响应式
               // 传递数据时,使用 computed 函数进行传递,函数中接收一个回调作为参数。在回调函数中通过 return 返回值将数据共享出去
                msg: computed(() => { return this.msg })
               /* 注意:
                    这里使用箭头函数,此时的 this 指向的还是当前组件实例对象。
                    但如果使用 function ,注意 this 指向问题
              */
           }
        }
    }
</script>
<!-- Grandson.vue  孙组件 -->

<template>
    <div>
	<!-- 因为爷组件传递的是 响应式数据 所以在 孙组件 中必须使用 .value 才能正常使用数据 -->
        <!-- 如果传递的不是响应式的数据,直接使用名称即可 -->
	<h2>Grandson 孙组件--{{ msg.value }}</h2>
    </div>
</template>

<script>
    export default{
        // 定义 inject 节点接收 爷组件 向下共享的数据--- inject里的数据可以在模版中直接使用,在实例中也可以通过 this 访问到
        inject: ["msg"]
  }
</script>