请说一下vue的组件通信有哪些?
答:vue的组件通信分为3类:父子通讯,子父通讯,跨级通讯。父子通讯,父组件通过属性传值,子组件通过props接收,props接收时有两种写法,第一种是数组,第二种是对象,对象可以做参数的校验等。子父通讯,父组件传递一个函数给子组件,子组件通过调用父组件传递的函数来传递参数。跨级通讯,可以通过provide/inject、$attrs、$bus、vuex等实现。
为什么需要组件通讯?
vue是组件化开发,我们项目代码中的各个模块都是通过组件组合而成,而且组件之间的参数都会有相互依赖的关系,所以我们需要熟练掌握组件通讯
组件通讯的分类:
- 父子组件
- 同级组件
-
1、父子通讯:
父组件向子组件Child传递参数:
attr1 静态传参
arr2 动态传参
<template>
<Child attr1="msg" :attr2="msg">this is header</Child>
</template>
<script>
import Child from "./child";
export default {
name: 'Header',
data(){
return {
msg:"12323"
}
},
components:{
Child
}
};
</script>
子组件:
子组件通过props来获得父组件传递的参数数组 简单
- 对象 完整
<template>
<div>这里是子组件</div>
</template>
<script>
export default {
name: 'Child',
// props两种写法
// props:["attr1","attr2"],
props:{
attr1:{
type:"String|Number|Boolean|Null|Undefined|Array|Object|Function",
default:"默认值",
require: true|false
}
}
};
</script>
子父通讯
子: this.$emit('事件名',"任意数据类型的值")
父:v-on:事件名="回掉函数"
父组件-子组件传递一个函数,子组件调用父组件传递过来的函数,传入参数,父组件传递的这个函数就可以通过回调形参,拿到子组件传递的参数
跨级通讯
- Vue v2.2新增 provide/inject
父组件
<template>
<div></div>
</template>
<script>
export default {
provide:{
key:val,
...
}
};
</script>
子组件
<template>
<div></div>
</template>
<script>
export default {
name: "DialogFooot",
inject:["key1",...],
};
</script>
- Vue v2.4新增 $attrs
想要使用$attrs 在父组件中不可以通过props去定义
祖先组件:
<template>
<div>
<Parent :key1="key1" :key2="key2" ...></Parent>
</div>
</template>
<script>
export default {
name: "Origine",
data(){
return {
key1:val1,
key2:val2
}
}
};
</script>
父组件 - parent:
<template>
<div>
// 父组件可以通过$attrs获得祖先组件中的数据
// 不需要通过props去接受
{{$attrs}}
<Child v-bind="$attr"></Child>
</div>
</template>
<script>
export default {
name: "Parent",
inheritAttrs: false,
};
</script>
子组件:
<template>
<div>
// 子组件需要获得父组件的参数,父组件通过v-bind将$attr绑定
{{$attrs}}
</div>
</template>
<script>
export default {
name: "Child",
inheritAttrs: false,
mounted(){
// js方式
console.log(this.$attrs)
}
};
</script>
EventHub & EventBus
由于vue原生支持发布、订阅模式,我们通过 new Vue() 创建新的实例。
utils/hub.js
import Vue from 'vue';
export default new Vue();
main.js
import Vue from "vue";
import App from "./App.vue";
import router from "./router";
Vue.config.productionTip = false;
import EventHub form "@/utils/events"
Vue.prototype.$eventHub = EventHub;
new Vue({
router,
render: h => h(App),
}).$mount("#app");
组件内部:
子:this.$eventhub.emit('eventname',callback);
父:this.$eventhub.$on('event',callback)