8种vue组件通信方式详细解析实例

对于vue来说,组件是非常常见的,有很多平台都封装了了属于自己一套的组件,如element ui、we ui等等。同时组件之间的消息传递也是非常重要的,下面是我对组件之间消息传递的各种方式的总结,共有8种方式。如有不足之处,可以留言补充,互相学习。

我们提供的服务有:网站制作、成都网站设计、微信公众号开发、网站优化、网站认证、寿光ssl等。为上千家企事业单位解决了网站和推广的问题。提供周到的售前咨询和贴心的售后服务,是有科学管理、有技术的寿光网站制作公司

1. props和$emit

这是最最常用的父子组件通信方式,父组件向子组件传递数据是通过prop传递的,子组件传递数据给父组件是通过$emit触发事件来做到的。 实例:

父组件

 
 
 
 
  1. Vue.component('parent',{ 
  2.  template:` 
  3.  
     
  4.  

    父组件

     
  5.   
  6.  
 
  •  `, 
  •  data(){ 
  •  return { 
  •  message:'Hello web秀' 
  •  } 
  •  }, 
  •  methods:{ 
  •  //执行子组件触发的事件 
  •  getChildData(val){ 
  •  console.log(val) 
  •  } 
  •  } 
  • }) 
  • var app=new Vue({ 
  •  el:'#app', 
  •  template:` 
  •  
     
  •   
  •  
  •  
  •  ` 
  • }) 
  • 子组件

     
     
     
     
    1. Vue.component('child',{ 
    2.  //得到父组件传递过来的数据 
    3.  props:['message'], 
    4.  data(){ 
    5.  return { 
    6.  myMessage: this.message 
    7.  } 
    8.  }, 
    9.  template:` 
    10.  
       
    11.    
    12.  
     
  •  `, 
  •  methods:{ 
  •  passData(val){ 
  •  //触发父组件中的事件 
  •  this.$emit('getChildData',val) 
  •  } 
  •  } 
  • }) 
  • 解析:

    2. $attrs和$listeners

    ***种方式处理父子组件之间的数据传输有一个问题:如果多层嵌套,父组件A下面有子组件B,组件B下面有组件C,这时如果组件A想传递数据给组件C怎么办呢?

    如果采用***种方法,我们必须让组件A通过prop传递消息给组件B,组件B在通过prop传递消息给组件C;要是组件A和组件C之间有更多的组件,那采用这种方式就很复杂了。从Vue 2.4开始,提供了$attrs和$listeners来解决这个问题,能够让组件A之间传递消息给组件C。

    C组件

     
     
     
     
    1. Vue.component('C',{ 
    2.  template:` 
    3.  
       
    4.   
    5.   
    6.  `, 
    7.  methods:{ 
    8.  passCData(val){ 
    9.  //触发父组件A中的事件 
    10.  this.$emit('getCData',val) 
    11.  } 
    12.  } 
    13. }) 

    B组件

     
     
     
     
    1. Vue.component('B',{ 
    2.  data(){ 
    3.  return { 
    4.  myMessage:this.message 
    5.  } 
    6.  }, 
    7.  template:` 
    8.  
       
    9.   
    10.   
    11.   
    12.  `, 
    13.  //得到父组件传递过来的数据 
    14.  props:['message'], 
    15.  methods:{ 
    16.  passData(val){ 
    17.  //触发父组件中的事件 
    18.  this.$emit('getChildData',val) 
    19.  } 
    20.  } 
    21. }) 

    A组件

     
     
     
     
    1. Vue.component('A',{ 
    2.  template:` 
    3.  
       
    4.  

      this is parent compoent!

       
    5.  
    6.  :messageC="messageC"  
    7.  :message="message"  
    8.  v-on:getCData="getCData"  
    9.  v-on:getChildData="getChildData(message)"> 
    10.   
    11.   
    12.  `, 
    13.  data(){ 
    14.  return { 
    15.  message:'Hello', 
    16.  messageC:'Hello c' 
    17.  } 
    18.  }, 
    19.  methods:{ 
    20.  getChildData(val){ 
    21.  console.log('这是来自B组件的数据') 
    22.  }, 
    23.  //执行C子组件触发的事件 
    24.  getCData(val){ 
    25.  console.log("这是来自C组件的数据:"+val) 
    26.  } 
    27.  } 
    28. }) 
    29. var app=new Vue({ 
    30.  el:'#app', 
    31.  template:` 
    32.  
       
    33.   
    34.   
    35.  ` 
    36. }) 

    解析:

    3. v-model

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

    子组件

     
     
     
     
    1. Vue.component('child',{ 
    2.  props:{ 
    3.  //v-model会自动传递一个字段为value的prop属性 
    4.  value: String,  
    5.  }, 
    6.  data(){ 
    7.  return { 
    8.  myMessage:this.value 
    9.  } 
    10.  }, 
    11.  methods:{ 
    12.  changeValue(){ 
    13.  //通过如此调用可以改变父组件上v-model绑定的值 
    14.  this.$emit('input',this.myMessage); 
    15.  } 
    16.  }, 
    17.  template:` 
    18.  
       
    19.  
    20.  type="text"  
    21.  v-model="myMessage"  
    22.  @change="changeValue"> 
    23.   
    24.  ` 
    25. }) 

    父组件

     
     
     
     
    1. Vue.component('parent',{ 
    2.  template:` 
    3.  
       
    4.  

      this is parent compoent!

       
    5.  

      {{message}}

       
    6.   
    7.   
    8.  `, 
    9.  data(){ 
    10.  return { 
    11.  message:'Hello' 
    12.  } 
    13.  } 
    14. }) 
    15. var app=new Vue({ 
    16.  el:'#app', 
    17.  template:` 
    18.  
       
    19.   
    20.   
    21.  ` 
    22. }) 

    4. provide和inject

    父组件中通过provider来提供变量,然后在子组件中通过inject来注入变量。不论子组件有多深,只要调用了inject那么就可以注入provider中的数据。而不是局限于只能从当前父组件的prop属性来获取数据,只要在父组件的生命周期内,子组件都可以调用。

    子组件

     
     
     
     
    1. Vue.component('child',{ 
    2.  inject:['for'],//得到父组件传递过来的数据 
    3.  data(){ 
    4.  return { 
    5.  myMessage: this.for 
    6.  } 
    7.  }, 
    8.  template:` 
    9.  
       
    10.   
    11.   
    12.  ` 
    13. }) 

    父组件

     
     
     
     
    1. Vue.component('parent',{ 
    2.  template:` 
    3.  
       
    4.  

      this is parent compoent!

       
    5.   
    6.   
    7.  `, 
    8.  provide:{ 
    9.  for:'test' 
    10.  }, 
    11.  data(){ 
    12.  return { 
    13.  message:'Hello' 
    14.  } 
    15.  } 
    16. }) 
    17. var app=new Vue({ 
    18.  el:'#app', 
    19.  template:` 
    20.  
       
    21.   
    22.   
    23.  ` 
    24. }) 

    5. 中央事件总线

    上面方式都是处理的父子组件之间的数据传递,那如果两个组件不是父子关系呢?也就是兄弟组件如何通信?

    这种情况下可以使用中央事件总线的方式。新建一个Vue事件bus对象,然后通过bus.$emit触发事件,bus.$on监听触发的事件。

     
     
     
     
    1. Vue.component('brother1',{ 
    2.  data(){ 
    3.  return { 
    4.  myMessage:'Hello brother1' 
    5.  } 
    6.  }, 
    7.  template:` 
    8.  
       
    9.  

      this is brother1 compoent!

       
    10.   
    11.   
    12.  `, 
    13.  methods:{ 
    14.  passData(val){ 
    15.  //触发全局事件globalEvent 
    16.  bus.$emit('globalEvent',val) 
    17.  } 
    18.  } 
    19. }) 
    20. Vue.component('brother2',{ 
    21.  template:` 
    22.  
       
    23.  

      this is brother2 compoent!

       
    24.  

      brother1传递过来的数据:{{brothermessage}}

       
    25.   
    26.  `, 
    27.  data(){ 
    28.  return { 
    29.  myMessage:'Hello brother2', 
    30.  brothermessage:'' 
    31.  } 
    32.  }, 
    33.  mounted(){ 
    34.  //绑定全局事件globalEvent 
    35.  bus.$on('globalEvent',(val)=>{ 
    36.  this.brothermessage=val; 
    37.  }) 
    38.  } 
    39. }) 
    40. //中央事件总线 
    41. var bus=new Vue(); 
    42. var app=new Vue({ 
    43.  el:'#app', 
    44.  template:` 
    45.  
       
    46.   
    47.   
    48.   
    49.  ` 
    50. }) 

    6. parent和children

     
     
     
     
    1. Vue.component('child',{ 
    2.     props:{ 
    3.       value:String, //v-model会自动传递一个字段为value的prop属性 
    4.     }, 
    5.     data(){ 
    6.       return { 
    7.         mymessage:this.value 
    8.       } 
    9.     }, 
    10.     methods:{ 
    11.       changeValue(){ 
    12.         this.$parent.message = this.mymessage;//通过如此调用可以改变父组件的值 
    13.       } 
    14.     }, 
    15.     template:` 
    16.       
       
    17.          
    18.        
    19.   }) 
    20.   Vue.component('parent',{ 
    21.     template:` 
    22.       
       
    23.         

      this is parent compoent!

       
    24.         test 
    25.          
    26.        
    27.     `, 
    28.     methods:{ 
    29.       changeChildValue(){ 
    30.         this.$children[0].mymessage = 'hello'; 
    31.       }//在此我向大家推荐一个前端全栈开发交流圈:619586920 突破技术瓶颈,提升思维能力 
    32.     }, 
    33.     data(){ 
    34.       return { 
    35.         message:'hello' 
    36.       } 
    37.     } 
    38.   }) 
    39.   var app=new Vue({ 
    40.     el:'#app', 
    41.     template:` 
    42.       
       
    43.          
    44.        
    45.     ` 
    46.   }) 

    7. boradcast和dispatch

    vue1.0中提供了这种方式,但vue2.0中没有,但很多开源软件都自己封装了这种方式,比如min ui、element ui和iview等。 比如如下代码,一般都作为一个mixins去使用, broadcast是向特定的父组件,触发事件,dispatch是向特定的子组件触发事件,本质上这种方式还是on和on和emit的封装,但在一些基础组件中却很实用。

     
     
     
     
    1. function broadcast(componentName, eventName, params) { 
    2.  this.$children.forEach(child => { 
    3.  var name = child.$options.componentName; 
    4.  if (name === componentName) { 
    5.  child.$emit.apply(child, [eventName].concat(params)); 
    6.  } else { 
    7.  broadcast.apply(child, [componentName, eventName].concat(params)); 
    8.  } 
    9.  }); 
    10. export default { 
    11.  methods: { 
    12.  dispatch(componentName, eventName, params) { 
    13.  var parent = this.$parent; 
    14.  var name = parent.$options.componentName; 
    15.  while (parent && (!name || name !== componentName)) { 
    16.  parentparent = parent.$parent; 
    17.  if (parent) { 
    18.  name = parent.$options.componentName; 
    19.  } 
    20.  } 
    21.  if (parent) { 
    22.  parent.$emit.apply(parent, [eventName].concat(params)); 
    23.  } 
    24.  }, 
    25.  broadcast(componentName, eventName, params) { 
    26.  broadcast.call(this, componentName, eventName, params); 
    27.  } 
    28.  } 
    29. }; 

    8. vuex处理组件之间的数据交互

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

    当前名称:8种vue组件通信方式详细解析实例
    网页路径:http://www.shufengxianlan.com/qtweb/news39/409689.html

    网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等

    广告

    声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联

    猜你还喜欢下面的内容

    解决方案知识

    行业网站建设