父子组件间的通讯,其实很简单,在前文好多地方都涉及到了,只是没有专门提及。
不过,组件通讯里边有个坑,帮大家绕一绕。
App组件和Aside(menu)组件,Aside组件通过App组件控制内容区显示,最适合展示这个内容。
先来看前面提过的一张图:
组件交互.PNG
我们就其中的虚线一部分进行分析:
- 父组件通过【props】与子组件通讯
- 子组件通过【事件】向父组件传递信息
显而易见的,父组件通过props可以控制子组件显示的内容,子组件通过发送事件,父组件响应事件,改变自身。这么简单,当然没什么说的。关键是“坑”。
在说坑前,先说这种父子通讯模式的的限制
- 平行组件间的通讯受限制。可以通过一条通讯总线,把同级别间的组件挂在总线上通讯。
- 爷孙组件通讯,还得麻烦父组件,倘若祖父和从孙呢,倘若...
第一个问题,有vuex,麻烦一点就是了。这种其实可以通过设计模式避免。
第二个问题,ElementUI给出一个办法,可以参考'element-ui/src/mixins/emitter'
这种广播模式。当然这种广播模式也能解决第一个问题。有点怪怪的就是了,不太符合代码洁净的原则。我们后面会和这个东西打交道,这里先提一下。
下面通过代码看《坑》:(这段代码不能直接运行!!!了解意思得了)
当父组件响应事件时,可能给自己添加新属性,这时候会出现问题。
/* 子组件 **/
{
template: '<div @click="onClick">{{value}}</div>',
props: ['name', 'value'],
// ...
methods: {
onClick() {
this.$emit('add', this.name, Math.random());
},
},
}
/* 父组件 **/
{
template: '<child name="name" :value="values['name']" @add="onAdd">';
// 更一般的情况是,values来自props,同时爷组件甚至没有给values传递值
data {
return {
values: undifined;
};
},
// ...
methods: {
onAdd(name, value) {
// 悲剧再这里发生
this.values[name] = value;
},
},
}
悲剧出现了,单击后,什么也没发生...,不是应该每次换一个随机数吗?父组件通过props控制不了子组件了?
问题跃然纸上了:
vue文档有这么一句话:如果在实例创建之后添加新的属性到实例上,它不会触发视图更新。
在我们的这套系统中,这个问题后面会碰到的。添加新属性的坑大家都能绕过,但是祖孙三个组件混在一起,通讯混在一起,就不太起眼了,成了陷阱。解决办法是$set:this.$set(this.values, name, value);
。
网友评论