组件间的互动大概有这几种情况:
1.父子间的互动:watch,props,$emit,这几个属性,可以涵盖父子组件间的互动。
父页面中:
menu-aside组件的加载要随着页面的projectId的变动而变动,这时候,在menu-aside组件中用props属性接收父传来的projectId,并用watch监听:
props:[projectId],
watch:{
projectId(){
//当projectId变动的时候要执行的方法
}
}
那如果子组件变化,要求父组件互动,怎么办呢:
父页面加一个接收机智 @changeFather ,接收到子组件执行的$emit('changeFather',obj); 动作就会调用到reload方法
methods:{
reload(obj){
//根据参数执行变化
}
}
2.非父子之间组件通信:
1)子==父==子
子组件A 通过$emit 触发父组件,父组件通过某个(如:projectId)对象的变化,触发子组件B的watch中监听的对象(如:projectId)的变动而执行对应的方法,从而达到A-B组件间的互动。
2)定义事件管理中心:可以new一个空Vue做为事件总线。
var msgCenter = new Vue();
在a组件和b组件中引入 msgCenter:msgCenter.$emit('key',value) ; msgCenter.$on('key',function(value){ xxx});
这样就能实现两个组件间的通讯了,对比1)减少了中间层的交互。
3)使用Vuex,vuex是一个专为 Vue.js 应用程序开发的状态管理模式,相对于中大型单页面应该推荐使用,小型单页面应用可能会增加过多繁琐冗余的。(vuex的介绍放到后面)
接下来我们了解一下watch,watch是一个实时监听,那么问题来了:
1.监听一个值与监听一个对象属性有什么区别?
深度监听,可以监听对象、数组的变化,开启deep:true的属性。
监听一个值 key=1,和一个对象 obj={ name:1}:
watch:{
key(val,oldVal){
console.log("key: "+val, oldVal);
},
obj:{
name(val,oldVal){
console.log("name: "+val, oldVal);
}
deep:true
}
}
这时候 key:1,2;name:2,2;对象的属性只显示了最新的值,旧的值没监控到。如果想要监控到对象的旧值,那就要通过监控方法来获取。
computed: {
findObjChange() {
return this.obj.name;
}
}
watch:{
findObjChange(val, oldVal){
console.log("obj.name: "+val, oldVal);
}
},
这时候打印出obj.name:1,2;
2.监听的对象太多是否会影响性能?
当监听一个tree对象时,测试数据达到100条,deep:true开启后,监控的属性就会达到一定量,这时候页面也许会产生卡顿延迟,这是因为监控的dom太多,导致性能受到影响。当deep改为false,页面又会流畅了。
3.监听使用deep:true,因对象数据太大,导致卡顿,怎么规避?
其实,父组件调动子组件,有的时候并不一定要用watch去监听联动,其实还可以用$refs对dom对象去操作。前提条件是组件是已经加载完毕的情况下,那这种前提,就必须在组件mounted初始化的时候加载好一遍,当父组件一个值发生变化的时候,通过this.$refs.searchInit.getProjectName(this.projectId);这种方式去调用子组件的方法实现互动。