Vue 组件之间的通信

4/9/2022 vue

# props / $emit 适用于父子组件通信

  • 父组件向子组件传参:prop
  • 子组件向父组件传递数据:$emit

# ref $parent / $children(vue3废弃) 适用于父子组件通信

  • ref :可以作用在子组件上、引用就指向组件实例
  • $parent / $children 访问父组件的属性或方法 / 访问子组件的属性或方法

# EventBus ($emit / $on)适用于父子、隔代、兄弟组件通信

  • 这种方法通过一个空的 Vue 实例作为中央事件总线(事件中心),用它来触发事件和监听事件
  • 自己封装的EventBus类
class EventBus{
        constructor() {
            this.eventList = {};
        };
        on (name,fn) {
            if(this.eventList[name]){
                this.eventList[name].push(fn);
            } else {
                this.eventList[name] = [fn];
            }
        };
        off(name,fn){
            if (arguments.length === 1) {
                if(this.eventList[name]){
                    delete this.eventList[name];
                }
            } else {
                let tasks = this.eventList[name];
                let index = tasks.findIndex(ele=>ele===fn);
                if(index >= 0){
                    tasks.splice(index,1);
                }
            }
        };
        emit(name,...args){
            if(this.eventList[name]){
                let tasks = this.eventList[name];
                tasks.forEach(fn=>{
                    fn(...args);
                })
            }
        };
    }
    let eventBus = new EventBus();
    let fn1 = (val,val2)=>{
        console.log(`fn1函数${val}${val2}`);
    };
    let fn2 = (val)=>{
        console.log(`fn2函数${val}`);
    };
    eventBus.on('add',fn1);
    eventBus.on('add',fn2);
    eventBus.off('add',fn2);
    eventBus.emit('add','111','222');
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44

# $attrs / $listeners(vue3废弃) 适用于隔代组件通信

  • $attrs用于父组件隔代向孙组件传值
    • 用在子组件中,子组件的$attrs中包含了所有除了本组件props之外的父组件属性。
    • 孙组件可以获取到未被子组件props接收的属性
    // 在子组件中
    <grand-child v-bind="$attr"/>
    // 在孙组件中
    props: {
        name: {
            type: String
        }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
  • $listeners用于孙组件隔代向父组件传值
    • 子组件作为父组件和孙组件的传递中介,在儿子组件中给孙子组件添加v-on="$listeners",这样父组件才能接收到孙组件的数据
    // 父组件中
    <child @changeData="changeMyData"></child>
    // 子组件中
    <grand-child v-on="$listeners"></grand-child>
    // 孙组件中
    methods: {
        edit() {
        // 发送事件
        this.$emit("changeData", this.data1);
        }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11

# provide / inject 适用于隔代组件通信

祖先组件中通过 provider 来提供变量,然后在子孙组件中通过 inject 来注入变量。 provide / inject API 主要解决了跨级组件间的通信问题,不过它的使用场景,主要是子组件获取上级组件的状态,跨级组件间建立了一种主动提供与依赖注入的关系

# $root 适用于隔代组件通信

访问跟组件中的属性和方法,只对根组件有用

# Vuex 适用于隔代组件通信

  • Vue的状态管理工具
  • Vuex的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新。
  • 改变 store 中的状态的唯一途径就是显式地提交 (commit) mutation。这样使得我们可以方便地跟踪每一个状态的变化。

# 总结

  • 父子组件:props/$emit/$parent/ref
  • 兄弟组件:$parent/eventbus/vuex
  • 跨层级关系:eventbus/vuex/provide+inject/$attrs + $listeners/$root
Last Updated: 4/18/2023, 2:49:49 PM
晴天
周杰伦