Vue组件之间的通信传参
Vue组件中,涉及到多种组件之间的通信状态,分别是,父组件向子组件传递参数通信,或子组件向父组件传递参数通信,还有一种就是同级的兄弟组件之间传递参数通信,以及爷孙组件之间的互相通讯状态。
1.父组件向子组件发起传递参数通信(Props)
1.首先在子组件中需要暴露接收参数传递的接口
props: {//完整版写法,指定了 类型,控制了,必要性,,提供了默认值
ueername: {
type: String, //接收类型
required: true, // 是否必传
default: "备用数据", //默认数据
},
},
//一般写法,只限制传入类型
props: {
ueername: String,
},
props: ["ueername"], //简化版写法,不做限制
2.父组件
<SiblingCom ueername="传递的数据"/>
//可v-bind 动态绑定
2.子组件向父组件发起传递参数通信(自定义事件)
1.子组件
<template>
<div class="about">
<button @click="steredata">点击传递数据</button>
</div>
</template>
methods: {
steredata() { //子组件中,原生节点事件触发后,紧接着定义一个自定义事件,this.$emit,接收两个参数,第一个参数是String,自定义事件的事件名,第二个参数为携带传递的参数,传递多个数据时,以整合对象的形式传。
this.$emit("parameters","我是传递的参数")
},
// 在当前组件销毁时,建议卸载或解绑自定义事件,解绑多个事件时,采用数组的写法解绑
beforeDestroy() {
this.$off('parameters')
},
},
2.父组件
<template>
<div class="home">
<SiblingCom @parameters="Receive" /> //组件外部,绑定自定义事件名,再指向具体事件
</div>
</template>
methods: {
Receive(x) { //接收一个参数,传递过来的数据。
console.log(x); //我是传递的参数
},
},
拓展:自定义事件还可以通过 ref 属性 来直接拿到组件实例对象绑定事件。
父组件补充ref写法
<template>
<div class="home">
<SiblingCom ref="rootref" /> //采用ref获取到组件实例
</div>
</template>
methods: {
Receive(x) { //接收一个参数,传递过来的数据。
console.log(x); //我是传递的参数
},
},
mounted() { //ref绑定事件
this.$refs.rootref.$on("parameters",this.Receive);
}
ref自定义事件的写法优势是:事件可以不被立即绑定,可以通过异步处理后再绑定,对于开发者来说灵活度相对更高!
3.同级兄弟组件之间传递参数通信(全局事件总线)
1.第一步,在main.js中,安装全局配置事件总线,定义一个新的全局对象$bus,并且把它挂载到Vue实例的 prototype 原型链上。
new Vue({
beforeCreate() {
Vue.prototype.$bus = this //全局安装配置全局事件总线
},
router,
store,
render: h => h(App)
}).$mount('#app')
这里以兄弟组件 A 向 兄弟组件 B 传递通信为演示
1.首先在需要接收参数的组件中,声明并监听一个事件。
<template>
<div class="about">
<h1>兄弟组件B</h1>
<h5>接收组件1传递过来的:{{ name }}</h5>
</div>
</template>
mounted() {
this.$bus.$on("Receive", this.parameters); //声明监听事件
},
methods: {
parameters(x) { //接收兄弟组件传递过来的参数
console.log(x);
this.name = x;
},
},
2.组件A 中原生节点事件触发后,立即回调触发,上面所定义的监听事件。
<template>
<div class="about">
<h1>兄弟组件A</h1>
<button @click="steredata">点击传递数据</button>
</div>
</template>
methods: {
steredata() {
this.$bus.$emit("Receive", "我是传递过来的值");
},
},
// 在当前组件销毁时,建议卸载或解绑自定义事件
beforeDestroy() {
this.$bus.$off('Receive')
},
4.爷孙组件之间的通讯传递状态 ($attrs和 $listeners)
(1).爷组件给孙组件传递参数,在孙子组件中正常定义props接口,接收参数
<template>
<div>
<h1>我是孙子组件,我接受了爷爷组件的:::{{name}}</h1>
</div>
</template>
<script>
export default {
props: {
name: String,
},
};
</script>
父组件 ,父组件中不用定义props接口。需要绑定 一个 v-bind=“$attrs”。
<template>
<div class="about">
<h1>父组件</h1>
<About v-bind="$attrs"/>
</div>
</template>
<script>
import About from "../views/AboutView.vue";
export default {
components: {
About,
},
};
</script>
爷爷组件中,按正常的父传子的形式传
<template>
<div class="home">
<h1>爷爷组件</h1>
<SiblingCom :name="grandpaname" />
</div>
</template>
<script>
import SiblingCom from "@/components/SiblingCom.vue";
export default {
name: "HomeView",
components: {
SiblingCom,
},
data() {
return {
grandpaname: "给孙子的数据",
};
},
};
</script>
(2)孙子组件给爷爷组件传递参数,在孙子组件中通过 this.$emit(),正常定义自定义事件,并传递参数。
<template>
<div>
<button @click="daetclick">孙子组件</button>
</div>
</template>
<script>
export default {
methods:{
daetclick(){
this.$emit("boock","孙传给爷的数据")
}
}
};
</script>
父组件中,不需要接收触发自定义事件,需要绑定 属性 v-on=“$listeners”
<template>
<div class="about">
<h1>父组件</h1>
<About v-on="$listeners"/>
</div>
</template>
<script>
import About from "../views/AboutView.vue";
export default {
components: {
About,
},
};
</script>
爷组件中,正常接收触发自定义事件。
<template>
<div class="home">
<h1>我是爷爷组件接收到了孙子传过来的值::{{grandson}}</h1>
<SiblingCom @boock="names" />
</div>
</template>
<script>
import SiblingCom from "@/components/SiblingCom.vue";
export default {
name: "HomeView",
components: {
SiblingCom,
},
data() {
return {
grandson:"",
}
},
methods: {
names(val) {
this.grandson = val;
},
},
};
</script>
点击孙子组件按钮后:
概述:$attrs和 $listeners ,作用在父组件上,父组件扮演了一个中间商代理的任务,其他操作不变。