vue的通信方式(二)---祖父孙三个级别的之间的隔代通信
在之前的文章中我们提到了vue常用的几种通信方式,如父子,子父,以及兄弟组件之间的通信,可以通过这个传送门了解他们:Vue通信方式(一)当我们如果遇到祖组件,父组件,孙组件,三个级别嵌套时,我们该怎么在祖组件与孙组件之间通信呢,当然通过本地存储或者Vuex都可以实现,但仅仅是一个值得时候未免有点小题大做了,或者是组件之间的通信那样一级一级传?有点麻烦,在此,我们就详解如何实现祖孙之间的通信。...
在之前的文章中我们提到了vue常用的几种通信方式,如父子,子父,以及兄弟组件之间的通信,可以通过这个传送门了解他们:Vue通信方式(一)
当我们如果遇到祖组件,父组件,孙组件,三个级别嵌套时,我们该怎么在祖组件与孙组件之间通信呢,当然通过本地存储或者Vuex都可以实现,但仅仅是一个值得时候未免有点小题大做了,或者是组件之间的通信那样一级一级传?有点麻烦,在此,我们就详解如何实现祖孙之间的通信。
首先我们来看看vue新增的两个属性:$attrs和$listeners,这是vue2.4新增的两个属性,我们来看看官方文档是怎么解释的吧。
好吧,对于第一次看的童鞋来说,并不知道他在BB什么, 简要的讲就是,$attrs可以获取父作用域传入的值(不包括props中的),$listeners相当于父作用域的事件监听器,那我们就可以用这两个属性实现祖孙之间的数据通信
首先,我们定义一个祖级别的组件:father1.vue
<template>
<h6>父组件:
<p>这是来自c组件的数据:{{msg1}}</p>
<div>
<B :messagec="messagec" :msgc="msgc2" v-on:getCData="getCData"></B>
</div>
</h6>
</template>
<script>
import B from './son.vue'
export default{
data() {
return {
messagec:{a:1,c:2}, //传递给c组件的数据,可以传对象,字符串以及其他类型
msg:'',
msg1:'',
msgc2:'第二个传给孙组件的值'
}
},
components:{
B
},
methods:{
//执行C子组件触发的事件
getCData(val){
console.log("这是来自C组件的数据:"+val)
this.msg1=val
}
}
}
</script>
然后在定义一个父级别的组件:son.vue,相当于祖孙通信之间的中间件
<template>
<h1>这是子组件:
<div>
<p>这是B组件</p>
<!-- C组件中能直接触发getCData的原因在于 B组件调用C组件时 使用 v-on 绑定了$listeners 属性 -->
<!-- 通过v-bind 绑定$attrs属性,C组件可以直接获取到A组件中传递下来的props(除了B组件中props声明的) -->
<C v-bind="$attrs" v-on="$listeners"></C>
</div>
</h1>
</template>
<script>
import C from './c.vue' // 引入C组件
export default{
data(){
return {
mymessage:''
}
},
components:{
C
},
props:{
// messagec:String // 当在这个组件声明了传向C组件的值时,C组件则通过$attrs.messagec得不到该值,相当于被拦截了,要传给C,则不能在此声明
},
methods:{
}
}
</script>
主要是绑定两个属性v-bind="$attrs" v-on="$listeners",并且不能在props中声明传入的值,"$attrs"用于接受father.vue传入的值,$listeners用于监听触发事件传值给father.vue.
最后我们定义一个孙级别的组件:c.vue
<template>
<h1>这是C组件:
<p>接受来自father的值:{{$attrs.messagec.a}}</p>
<p>接受来自father第二个的值:{{$attrs.msgc}}</p>
<input type="text" v-model="msgtofather" @input="passCData(msgtofather)">
</h1>
</template>
<script>
export default{
data(){
return{
msgtofather:'' //传给father组件的值
}
},
props:{
// messagec:String // 当在这个组件声明了传向C组件的值时,C组件则通过$attrs.messagec得不到该值,相当于被拦截了,要传给C,则不能在此声明
},
methods:{
passCData(val){
//触发父组件father中的事件
this.$emit('getCData',val)
}
}
}
</script>
注意:此组件中props也不能声明父组件传入的值,否则$attrs.messagec.a会取不到该值,并且可以接受多个来自祖组件的值
最后,组件通信的测试图如下:
二、父组件触发子组件事件方式
定义一个子组件:
<template>
<div>子组件</div>
</template>
<script>
export default {
data() {
return {}
},
created() {},
mounted() {
this.$on('bridge', (val) => {
this.sonHandle()
})
},
methods: {
sonHandle() {
console.log('触发了子组件事件')
}
}
}
</script>
<style>
</style>
父组件中使用:
<template>
<div>
<son ref="son1"></son>
<el-button type="primary" size="mini" @click="touchSon" icon="el-icon-search">触发子组件事件</el-button>
</div>
</template>
<script>
import son from './index2.vue'
export default {
components: {
son
},
data() {
return {}
},
created() {},
methods: {
touchSon() {
this.$refs.son1.$emit('bridge')
}
}
}
</script>
<style>
</style>
效果图:
更多推荐
所有评论(0)