8.4 Vue组件常用的7种通信方式——第8章 Vue组件进阶

8.4 Vue组件常用的7种通信方式

Vue组件间通信方式有以下7种,已经学习过的不在此讲解了:

1、父子props和$emit通信:父向子通过props传值;子向父通过events ($emit)事件传值,代码示例中多次用到,不再讲解。

2、$attrs和$listeners方式通信

应用场景是如果父组件A下面有子组件B,组件B下面有子组件C,这时如果组件A想传递数据给孙子组件C怎么办呢?示例代码如下:

Vue.component('C',{
 
template:`
            <div>
                <input type="text" v-model="$attrs.messagec" @input="passCData($attrs.messagec)"> </div>
        `
,
 
methods:{
   
passCData(val){
     
//触发父组件A中的事件
      this.$emit('getCData',val)
    }
  }
})


Vue.component('B',{
 
data(){
   
return {
     
mymessage:this.message
   
}
  },
 
template:`
            <div>
                <input type="text" v-model="mymessage" @input="passData(mymessage)">
                <!-- C
组件中能直接触发getCData的原因在于 B组件调用C组件时 使用 v-on 绑定了$listeners 属性 -->
                <!--
通过v-bind 绑定$attrs属性,C组件可以直接获取到A组件中传递下来的props(除了B组件中props声明的) -->
                <C v-bind="$attrs" v-on="$listeners"></C>
            </div>
        `
,
 
props:['message'],//得到父组件传递过来的数据
  methods:{
   
passData(val){
     
//触发父组件中的事件
      this.$emit('getChildData',val)
    }
  }
})

Vue.component('A',{
 
template:`
            <div>
                <p>this is parent compoent!</p>
                <B :messagec="messagec" :message="message"
v-on:getCData="getCData" v-on:getChildData="getChildData(message)"></B>
            </div>
        `
,
 
data(){
   
return {
     
message:'hello',
     
messagec:'hello c' //传递给c组件的数据
    }
  },
 
methods:{
   
getChildData(val){
     
console.log('这是来自B组件的数据')
    },
   
//执行C子组件触发的事件
    getCData(val){
     
console.log("这是来自C组件的数据:"+val)
    }
  }
})

var app=new Vue({
 
el:'#app',
 
template:`
            <div>
                <A></A>
            </div>
        `

})

代码重点讲解:

    最关键的一句代码是在组件B中,设置绑定$attrs和$listners,<C v-bind="$attrs" v-on="$listeners"></C>,组件B作为桥梁,打通组件A和组件C之间的联系。

 

3、多层嵌套通信:provide / inject

    在8.3.1组件的注入和依赖中讲解过。

 

4、中央事件通信

中央事件通信用于兄弟组件之间通信。

(1)首先定义一个bus.js文件

引入空的vue,实例化,曝光出去

import Vue from 'vue'
const Bus  = new Vue({})
export default Bus

(2)创建两个vue文件(兄弟组件)

值得注意的监听派发事件之后,要用ES6的箭头函数。

组件A

<template>
    <
div id="app">
        A
组件:{{msg}}
       
<!--定义任意事件-->
       
<button @click="brother">A组件</button>
    </
div>
</
template>

<
script>
   
//引入bus文件
    import bus from './bus.js'
   
export default {
       
data(){
           
return {
               
msg:'Bus通信'
           
}
        },
       
methods:{
           
brother(){
//          派发事件
                bus.$emit('A',this.msg)
            }
        }
    }

</script>

<
style>
</
style>

 

组件B

<template>
    <
div id="app">
        B
组件:{{msg}}
   
</div>
</
template>

<
script>
   
//引入bus文件
    import bus from './bus.js'
   
export default{
       
data(){
           
return{
               
msg:"Goddess"
           
}
        },
       
created(){
//      监听派发的事件
            bus.$on('A',(res)=>{
               
console.log(res)
               
this.msg = res
           
})
        }
    }

</script>

<
style>
</
style>

 

5、v-model

    父组件通过v-model传递值给子组件时,会自动传递一个valueprop属性,在子组件中通过this.$emit(‘input’,val),自动修改v-model绑定的父值。

Vue.component('child',{
 
props:{
   
value:String, //v-model会自动传递一个字段为valueprop属性
  },
 
data(){
   
return {
     
mymessage:this.value
   
}
  },
 
methods:{
   
changeValue(){
     
this.$emit('input',this.mymessage);//通过如此调用可以改变父组件上v-model绑定的值
    }
  },
 
template:`
            <div>
                <input type="text" v-model="mymessage" @change="changeValue">
            </div>
    })
    Vue.component('parent',{
        template:`
   
<div>
    <
p>this is parent compoent!</p>
   
<p>{{message}}</p>
<child v-model="message"></child>
 
</div>
   
`,
        data(){
            return {
                message:'hello'
            }
        }
    })
    var app=new Vue({
        el:'#app',
        template:`
 
<div>
  <
parent></parent>
 
</div>
   
`
    })

 

6、$parent和$children通信

    在父子访问的章节学过,不再讲解。

 

7、Vuex处理组件之间的数据交互

如果业务逻辑复杂,很多组件之间需要同时处理一些公共的数据,这个时候才有上面这一些方法可能不利于项目的维护,Vuex的做法就是将这一些公共的数据抽离出来,然后其他组件就可以对这个公共数据进行读写操作,这样达到了解耦的目的。Vuex的用法在后面章节会专门讲到,在此不再讲解。

----------------------------------------------------------------------------------------------------------------
本内容为《抹平Vue学习曲线》的部分章节,需要阅读完整书籍的,可以跟作者沟通。
----------------------------------------------------------------------------------------------------------------

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值