Vue组件间的通信

了解过Vue的人都知道,组件化在Vue中是一个相当重要的概念,组件化一方面可以提高代码的可读性,另一方面可以少写很多的代码,利于代码的维护,而组件间的通信也是我们经常遇到的操作。组件之间通信的方式可以分为三种,父组件与子组件通信,子组与父组件通信,兄弟组件间通信。

父组件与子组件通信

在Vue中,父子组件的关系可以总结为向下通过 prop 传递,向上通过事件传递。父组件通过 prop 给子组件下发数据,子组件通过事件给父组件发送消息。

一个组件默认可以拥有任意数量的 prop,任何值都可以传递给任何 prop。我们能够在组件实例中访问这个值,就像访问 data 中的值一样。

父组件:parent.vue

1
2
3
4
5
6
7
8
9
10
11
12
13
<template> 
<child :mgs="message"></child>
</template>

<script>
export default {
data() {
return {
message: 'hello world!',
}
}
}
</script>

子组件:child.vue

1
2
3
4
5
6
7
8
9
<template>
<div>{{msg}}</div>
</template>

<script>
export default {
props: ['mgs']
}
</script>

子组件与父组件通信

父组件与子组件通信,我们可以调用vue内建的$emit并传入事件的名字,来向父级组件触发一个事件,然后在父组件上监听这个事件。

子组件:child2.vue

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<template>
<div @click="tellParent">{{mgs2}}</div>
</template>

<script>
export default {
props: ['mgs2'],
methods: {
tellParent() {
this.$emit('listenChild2', 'hello world!');
}
}
}
</script>

父组件:parent2.vue

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<template> 
<child :mgs2="message2" @listenChild2="updateMgs2"></child>
</template>

<script>
export default {
data() {
return {
message2: 'hi!'
}
},
methods: {
updateMgs2(val){
this.message2 = val
}
}
}
</script>

在父组件中绑定一个listenChild2的事件,然后给这个事件添加updateMgs2方法,当子组件child2通过点击事件tellParent触发listenChild2的时候,父组件里面的updateMgs2方法就会执行,并且数据通过参数的形式传递给父组件,从而实现通信的功能。

此外,在父组件中也可以使用 $children 可以访问子组件,子组件也可以通过 $parent 访问父组件中的数据。

兄弟组件间通信

首先我先举个例子吗,便于我们理解:如果你想把你支付宝里的钱转到微信你会怎么做?我想大部分人都知道:现将支付宝里的钱提现到银行卡,然后将银行卡里的钱充值到微信里面

所以你可能也猜到了,对于同级间组件进行通信处理的方法是,新建一个Vue实例作为事件总线,然后通过这个Vue实例来监听和触发事件。具体实现如下:

  1. 在需要进行通信的同级组件引入event.js

    1
    2
    3
    import Vue from 'vue'; 
    let _bus = new Vue();
    export default _bus;
  2. 在兄弟组件A中使用$emit触发事件。

    组件A: componentA.vue

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    <template>
    <div @click="tellCompB">点击向组件B通信</div>
    </template>

    <script>
    import _bus from 'event.js'
    export default {
    props: ['mgs'],
    methods: {
    tellCompB() {
    _bus.$emit('listenCompA', 'from component A');
    },
    }
    }
    </script>
  3. 在兄弟组件B中使用$on监听事件。

    组件A: componentB.vue

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    <template> 
    <div class="component-B">{{message}}</div>
    </template>

    <script>
    import _bus from 'event.js'
    export default {
    data() {
    return {
    message: 'hi!'
    }
    },
    methods: {
    _bus.$on('listenCompA', data => this.message = data)
    }
    }
    </script>

当组件AcomponentA触发listenCompA时,组件BcomponentB中的监听事件listenCompA就会被触发,数据通过参数的形式传入,从而实现同级组件间通信。

其他

父组件通过$refs操作子组件

在Vue中,在父组件里可以通过ref属性拿到子组件,从而可以调用子组件的方法。

父组件:

1
<child ref="child1"></child>

然后父组件就可以通过$refs访问子组件的属性和方法了。

1
this.$refs.child1.child1Function

注意:ref属性的命名不能用驼峰。

###Vuex

对于一些简单的组件间的通信其实这些方式足够用了,如果一个页面涉及到很多的组件,那么这种方法就不是那么简洁了,这是就需要用到Vue中很重要的一个插件了Vuex

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。Vuex 也集成到 Vue 的官方调试工具 devtools extension,提供了诸如零配置的 time-travel 调试、状态快照导入导出等高级调试功能。

大家如果有兴趣的话可以去了解一下:What is Vuex?