事件总线
任意两个组件之间传值常用事件总线 ,适用于项目不大情况
自定义bus
// Bus:事件派发、监听和回调管理
class Bus {
constructor() {
this.callbacks = {};
}
$on(name, fn) {
this.callbacks[name] = this.callbacks[name] || [];
this.callbacks[name].push(fn);
}
$emit(name, args) {
if (this.callbacks[name]) {
this.callbacks[name].forEach((cb) => cb(args));
}
}
}
// main.js
Vue.prototype.$bus = new Bus();
// child1
this.$bus.$on('foo', handle);
// child2
this.$bus.$emit('foo');
vue自带bus
1、在main.js中引用$bus全局属性
// 事件总线
Vue.prototype.$bus = new Vue()
2、在a.vue页面注册bus.on 事件
mounted() {
this.$bus.$on('event-from-child2', msg => {
console.log('Child1:', msg);
alert(msg)
});
}
3、在b.vue页面触发Bus事件
methods: {
hansedss() {
this.$bus.$emit('event-from-child2', 'some msg from child2');
}
}
parent / root用法和bus一致,区别就是不需要绑定bus属性
拓展
1、父组件可以通过$children访问子组件实现父子通信。
// parent
this.$children[0].xx = 'xxx'
注意:$children不能保证子元素顺序
2、attrs/listeners
包含了父作用域中不作为 prop 被识别 (且获取) 的特性绑定 ( class 和 style 除外)。当一个组件没有
声明任何 prop 时,这里会包含所有父作用域的绑定 ( class 和 style 除外),并且可以通过 v-
bind="$attrs" 传入内部组件——在创建高级别的组件时非常有用。
// child:并未在props中声明foo
<p>{{$attrs.foo}}</p>
// listeners回调方法
<h3 v-on="$listeners">测试$listeners</h3>
// parent
<HelloWorld foo="foo" @click="ssddd"/>
文档
3、refs
获取子节点引用
// parent
<HelloWorld ref="hw"/>
mounted() {
this.$refs.hw.xx = 'xxx'
}
调用子组件方法同理
4、provide/inject
能够实现祖先和后代之间传值
// ancestor
provide() {
return {
foo: 'foo'
}
}
// descendant
inject: ['foo']
也可以直接将父组件this传递下去,子组件就能方位父组件的data信息了