父子组件传值
Vue之间都是单页应用,有时候一个界面会因为各种原因拆分成多个子组件,子页面,例如弹窗,轮播等等一些。
有时候父组件要向子组件的弹窗传值应该怎么做呢,vue的属性里面有个props,可以实现父子组件的通信
子组件只需要写这个props的属性,记得加上"",就可以得到父组件传下来的值,key值要和父组件传下来的一样
直接在子组件内部就可以使用到,加上this,和data里定义的属性一样
//父组件的代码,传了一个pageNum的key值下去,=后面是data里面定义的属性值
<recommend :pageNum="pageNum"></recommend>
//子组件
export default {
data(){
return{
}
},
//子组件只需要写这个props的属性,记得加上"",就可以得到父组件传下来的值
//直接在子组件内部就可以使用到,加上this,和data里定义的属性一样
props:['pageNum'],
}
那么到这儿父传值给子组件就可以了,但是vue是单向数据流动,什么意思呢,就是子组件不能去改变父组件的值,比这个时候子组件通过props拿到父组件的值,想改变他,this.pageNum = 6,如果你这么做的话应该会报错,如果没报错的话也不推荐这样使用。因为父组件的这个值可能在多个页面都在使用,子组件改变的话其他页面都会改变。我们还是需要在父组件统一做处理
子组件想改变父组件的值,需要通过$emit(),这个事件可以通过父组件绑定的事件,做到组件通讯,下面代码有详细说明。父组件绑定@事件名,子组件$emit调用就可以做到通信,调用的时候父组件methods里面的方法会自动执行
//父组件绑定的事件,:info="",这个是props属性,@popClose=""是父组件的事件
<Address :info="info" @popClose="popClose" @selectAddress="selectAddress"></Address>
//父组件事件
selectAddress(params) {//子组件通过事件传过来的值,可以是任意类型
console.log(params)
//父组件的data的值可以直接赋值,子组件通过事件改变了父组件的data属性
this.update = params
},
//关闭弹窗
popClose(params){
this.show = params
}
//子组件事件
selectAddr(addr, index) {
//通过$emit("父组件事件名","要改变的值")
this.$emit('selectAddress',this.addr[index])
//关闭弹窗
this.$emit('popClose',false)
},
兄弟组件、层级深的组件通信
接下来是兄弟组件,和层级比较深的组件怎么做到通讯,通过上面的方法其实也可以做到,a传父,父传b。也可以做到,但是层级组件比较深,这样写起来太过繁琐,也不好维护,于是有了eventbus,事件总线,可以做到跨组件通讯,其实有点类似vuex,大家可以先这么理解一下
在vue的原型上,挂载一个全局的vue对象,最好写在main点js里面,这样做全局引入
//在vue的原型上,挂载一个全局的vue对象,最好写在main点js里面,这样做全局引入
Vue.prototype.$bus= new Vue()
和父子通信的方法其实差不多,不过不用在组件里面绑定事件了,因为vue原型上挂载了,所以在vue的组件里面可以直接使用到,直接用this.$bus。他有两个事件,一个是传递,一个是监听接收,$emit()和$on
其实你可以理解为vuex里面的this.$store.commit("事件名","值"),是不是很眼熟,也是全局的数据状态管理。
//事件传递,事件名和值
this.$bus.$emit('nameOfEvent', {key:"value"});
//事件监听
this.$bus.$on('nameOfEvent',(params) => {
console.log(params)
})
事件总线还有个关闭事件的方法$off()
//关闭监听全部事件
this.$bus.$off()
//关闭某个事件监听
this.$bus.$off("事件名")
这样你就可以在任何组件和页面进行通讯,不管层级多深都可以实现,是不是很简单。
上面的方法都是vue内部可以实现的组件通信,其实还有别的方法可以实现,例如vuex和本地缓存,不过都需要我们自己去写监听事件,而组件通信已经帮我们做了
代码执行顺序
还有个组件的加载顺序和执行顺序,如果想要组件的methos里面的方法执行,需要先将子组件挂载到父组件上,子组件的生命周期才会调用和执行。父组件会先将子组件全部挂载之后,才会执行mounted()生命周期,将自己挂载。
所以写代码的时候记得顺序,如果子组件写了v-if将组件隐藏了,组件不会被执行。通讯的时候,代码就加载不出来。需要保证通讯的组件都挂载到了页面上,这样方法才会执行
如果这篇文章对你有帮助,记得点赞和收藏哦