vue组件间通信六种方式(完整版)

【稿件】

10年积累的网站建设、成都做网站经验,可以快速应对客户对网站的新想法和需求。提供各种问题对应的解决方案。让选择我们的客户得到更好、更有力的网络服务。我虽然不认识你,你也不认识我。但先做网站设计后付款的网站建设流程,更有内乡免费网站建设让你可以放心的选择与我们合作。

前言

组件是 vue.js强大的功能之一,而组件实例的作用域是相互独立的,这就意味着不同组件之间的数据无法相互引用。一般来说,组件可以有以下几种关系:

如上图所示,A 和 B、B 和 C、B 和 D 都是父子关系,C 和 D 是兄弟关系,A 和 C 是隔代关系(可能隔多代)。

针对不同的使用场景,如何选择行之有效的通信方式?这是我们所要探讨的主题。本文总结了vue组件间通信的几种方式,如props、$emit/$on、vuex、$parent/$children$attrs/$listeners和provide/inject,以通俗易懂的实例讲述这其中的差别及使用场景,希望对小伙伴有些许帮助。

本文的代码请猛戳github博客,纸上得来终觉浅,大家动手多敲敲代码!

方法一、props/$emit

父组件A通过props的方式向子组件B传递,B to A 通过在 B 组件中 $emit, A 组件中 v-on 的方式实现。

1.父组件向子组件传值

接下来我们通过一个例子,说明父组件如何向子组件传递值:在子组件Users.vue中如何获取父组件App.vue中的数据 users:["Henry","Bucky","Emily"]

 
 
 
 
  1. //App.vue父组件 
  2.  
  3.  
总结:父组件通过props向下传递数据给子组件。注:组件中的数据共有三种形式:data、props、computed

2.子组件向父组件传值(通过事件形式)

接下来我们通过一个例子,说明子组件如何向父组件传递值:当我们点击“Vue.js Demo”后,子组件向父组件传递值,文字由原来的“传递的是一个值”变成“子向父组件传值”,实现子组件向父组件值的传递。

 
 
 
 
  1. // 子组件 
  2.  
  3.  
  4. // 父组件 
  5.  
  6.  
总结:子组件通过events给父组件发送消息,实际上就是子组件把自己的数据发送到父组件。

方法二、$emit/$on

这种方法通过一个空的Vue实例作为中央事件总线(事件中心),用它来触发事件和监听事件,巧妙而轻量地实现了任何组件间的通信,包括父子、兄弟、跨级。当我们的项目比较大时,可以选择更好的状态管理解决方案vuex

1.具体实现方式:  

 
 
 
 
  1. var Event=new Vue(); 
  2. Event.$emit(事件名,数据); 
  3. Event.$on(事件名,data => {}); 

2.举个例子:兄弟组件有三个,分别是A、B、C,C组件如何获取A或者B组件的数据

 
 
 
 
  1.  
  2.      
  3.      
  4.      
 
  •  
  •   
     
  •     

    A组件:{{name}}

     
  •     将数据发送给C组件 
  •   
  •  
  •  
  •  
  •   
     
  •     

    B组件:{{age}}

     
  •     将数组发送给C组件 
  •   
  •  
  •  
  •  
  •   
     
  •     

    C组件:{{name}},{{age}}

     
  •    
  •  
  •  
  • 方法三、Vuex

    1.简要介绍Vuex原理

    Vuex实现了一个单向数据流,在全局拥有一个State存放数据,当组件要更改State中的数据时,必须通过Mutation进行,Mutation同时提供了订阅者模式供外部插件调用获取State数据的更新。而当所有异步操作(常见于调用后端接口异步获取更新数据)或批量的同步操作需要走Action,但Action也是无法直接修改State的,还是需要通过Mutation来修改State的数据。根据State的变化,渲染到视图上。

    2.简要介绍各模块在流程中的功能:

    3.Vuex与localStorage

    vuex 是 vue 的状态管理器,存储的数据是响应式的。但是并不会保存起来,刷新之后就回到了初始状态,具体做法应该在vuex里数据改变的时候把数据拷贝一份保存到localStorage里面,刷新之后,如果localStorage里有保存的数据,取出来再替换store里的state。

     
     
     
     
    1. let defaultCity = "上海" 
    2. try {   // 用户关闭了本地存储功能,此时在外层加个try...catch 
    3.   if (!defaultCity){ 
    4.     defaultCity = JSON.parse(window.localStorage.getItem('defaultCity')) 
    5.   } 
    6. }catch(e){} 
    7. export default new Vuex.Store({ 
    8.   state: { 
    9.     city: defaultCity 
    10.   }, 
    11.   mutations: { 
    12.     changeCity(state, city) { 
    13.       state.city = city 
    14.       try { 
    15.       window.localStorage.setItem('defaultCity', JSON.stringify(state.city)); 
    16.       // 数据改变的时候把数据拷贝一份保存到localStorage里面 
    17.       } catch (e) {} 
    18.     } 
    19.   } 
    20. }) 

    这里需要注意的是:由于vuex里,我们保存的状态,都是数组,而localStorage只支持字符串,所以需要用JSON转换:

     
     
     
     
    1. JSON.stringify(state.subscribeList);   // array -> string 
    2. JSON.parse(window.localStorage.getItem("subscribeList"));    // string -> array  

    方法四、$attrs/$listeners

    1.简介

    多级组件嵌套需要传递数据时,通常使用的方法是通过vuex。但如果仅仅是传递数据,而不做中间处理,使用 vuex 处理,未免有点大材小用。为此Vue2.4 版本提供了另一种方法,当一个组件没有声明任何 prop 时,这里会包含所有父作用域的绑定 (class 和 style 除外),并且可以通过 v-bind="$attrs" 传入内部组件。通常配合 interitAttrs 选项一起使用

     
     
     
     
    1. // demo.vue 
    2.