Vue组件间通信
1.props和$emit是最常用的,用于父子组件
2. 引用ref
<Child ref="child" />
// 使用子组件的属性
this.$refs.child.xxx
3. 使用$children和$parent
父组件调用子组件
this.$children[0].xxx = xxx
子组件调用父组件
this.$parent.xxx = xxx
4. 兄弟组件,通过共同祖辈组件搭桥
this.$parent.$on(eventName, handler);
this.$parent.$emit(eventName, data);
5. 根据第3和第4种方法可以得到启发,使用自己写一个emitter用于向上通知和向下广播
// 向父组件通知事件
Vue.prototype.$dispatch = function(eventName, data) {
let parent = this.$parent;
while (parent) {
parent.$emit(eventName, data);
parent = parent.$parent;
}
}
// 向所有子组件通知事件
function broadcast() {
if (this.$children && this.$children.length) {
const args = Array.from(arguments);
const eventName = args[0];
const data = args.slice(1);
this.$children.forEach(child => {
child.$emit(eventName, ...data);
broadcast.apply(child, args);
})
}
}
Vue.prototype.$broadcast = function() {
broadcast.apply(this, Array.from(arguments));
}
6. 祖先和后代,可以使用provide和inject,官方例子不建议修改,最好传初始值后就不改变
// 祖先
provide() {
return {
form: this
}
}
// 后代
inject: ['form']
7. 祖先和后代还可以使用$attrs和$listeners
<!-- 中间的组件,$attrs承接父组件的props,$listeners监听子组件的事件 -->
<component v-bind="$attrs" v-on="$listeners" />
8. 任意两个组件之间,可以使用事件总线eventBus或者Vuex(Vuex单独讲解)
// 使用Vue快速定义bus
Vue.prototype.bus = new Vue();
// 自定义bus
export default class Bus {
constructor() {
this.onCache = {};
this.emitCache = {};
this.paramCache = {};
}
$on(eventName, handler) {
if (!this.onCache[eventName]) {
this.onCache[eventName] = [];
}
this.onCache[eventName].push(handler);
if (this.paramCache[eventName]) {
handler(...this.paramCache[eventName])
}
}
$emit(eventName, ...data) {
if (this.onCache[eventName]) {
this.onCache[eventName].forEach(fn => {
fn(...data);
});
}
this.paramCache[eventName] = data;
}
$remove(eventName, fn) {
if (this.onCache[eventName]) {
if (fn) {
for(let i = 0, len = this.onCache[eventName].length; i < len; i++) {
if (fn === this.onCache[eventName][i]) {
this.onCache[eventName].splice(i, 1);
break;
}
}
} else {
this.onCache[eventName] = undefined;
this.paramCache[eventName] = undefined;
this.$emitCache[eventName] = undefined;
}
}
}
}
Vue.prototype.$bus = new Bus();
使用上面的自定义总线的,在监听之后,在组件销毁之前记得remove掉
created() {
this.$bus.$on('busEvent', this.onBusEventHandler);
}
beforeDestroy() {
this.$bus.$remove('busEvent', this.onBusEventHandler);
}
github地址能查看emitter和eventbus的用法
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。