e起飞young
一个前端码农的技术博客
vue2组件间的各种常用通信方式总结
[ 2020/12/12, 125阅, 0评 ]

1、vuex

不论是父子关系、兄弟关系、层层嵌套关系还是八竿子打不着的关系,都可以使用vuex来进行数据的传递或是做做中间处理。

vuex是vue的状态管理器,存储的数据是响应式的,但是并不会保存起来,刷新之后就回到了初始状态,一般在vuex里数据改变的时候存一份到localStorage或sessionStorage里面(看项目需求),刷新之后,如果localStorage里有保存的数据,取出来再替换store里的state即可。

ps:vuex最简单、最详细的入门文档

2、事件总线EventBus

通过新建一个js文件event-bus.js,引入vue, new一个vue实例EventBus再导出;然后其他文件中引入EventBus,就可以使用EventBus.$emit发送消息、EventBus.$on来监听接收消息。

几乎可以满足任意场景的数据传递,逻辑比较复杂项目庞大的还是乖乖的用vuex。

ps:Vue事件总线(EventBus)使用详细介绍

前端哈默:使用 Event Bus 实现兄弟组件通信

3、父子关系

props$emit

父组件A中通过v-bind(一般使用缩写“:”)绑定prop传值给子组件B,子组件B使用props接收来自父组件A的数据,prop必须在子组件B中声明,未声明的prop会出现在B组件的$attrs中且dom中能看到该属性(被绑定成了普通的attribute),而已声明的prop则会出现在B组件的$props中且dom中看不到该属性。

子组件B向父组件通信使用$emit方法来触发父组件A中通过v-on(一般使用缩写“@”)绑定的事件监听器,当然触发的时候可以传值。

ps:父组件通过v-model传值给子组件时,会自动传递一个value的prop属性,子组件中通过this.$emit('input', val)来修改父组件中v-model绑定的值。一般常用此方法来实现自定义的双向绑定。

$attrs$listeners

当父组件绑定的prop在子组件中未声明时,在子组件中可以使用$attrs来获取这些属性值;

父组件绑定的(不含.native修饰器的)事件监听器可以使用$listeners获取到并调用

ref方式

在父组件中给调用的子组件绑定一个ref假设取名为xxx,然后就可以使用$refs.xxx来访问到该子组件实例,从而获取其data或调用方法等。

$children$parent

$children获取到的是父组件引用的所有直接子组件的集合(所以它是一个数组),在父组件A中可以使用它来获取到其调用的所有子组件的各种信息。

$parent获取到的是父组件示例,在子组件B中可以使用它来获取其父组件的相关信息。

4、父子孙关系

子组件可以通过$props将父组件的props一起传给孙组件、$attrs来传递子组件中未经声明的props、$listeners来传递父组件的监听器。

父组件调用子组件:

<Son msg="HelloWorld" :data="[1,2,3]" @mylistener="doSth" />

子组件调用孙组件:

<Grandson v-bind="$attrs" />
<Grandson v-bind="$props" />
<Grandson v-bind="{...$props, ...$attrs}" />
<Grandson v-bind="{...$props, ...$attrs}" v-on="$listeners" />

子组件和孙组件中都可以使用this.$emit('mylistener', val)来触发父组件中的doSth方法。

5、兄弟组件之间的方法调用

假设父组件中使用了两个组件Brother1、Brother2

<Brother1 ref="brother1" />
<Brother2 ref="brother2" />

需要在Brother2中调用Brother1的方法假定为method1,可以使用

this.$parent.$refs.brother1.method1()

或者

const arr = this.$parent.$children
for(let i=0; i<arr.length; i++) {
  if (arr[i].$options.name === 'Brother1的name') {
    arr[i].method1()
    break
  }
}

另外还可以使用eventBus,在Brother2中eventBus.$emit('tel'),Brother1中

eventBus.$on('tel', () => {
  this.method1()
})

另外使用vuex配合watch也可以实现,定义一个特定的state假设为test,每次需要调用的时候commit改变test的值(可以使用时间戳),Brother2中监听test的值是否发生变化,发生变化就调用method1方法。

6、后记

本文仅记录vue的常用通信方式(例如还有provide/inject等方式)且仅做简述,各种方法的细节或详细使用请查阅官方文档或度娘谷歌。

ps:一篇文章看懂Vue.js的11种传值通信方式vue组件间通信六种方式

有朋自远方来...评论一下呗O(∩_∩)O

  • 搜索