组件传值(通信)式
父传后代(后代拿到了父的数据)
- 父组件引入子组件,绑定数据,
优点:子组件通过props来接收父组件绑定的数据。这种方式父传子很方便,但是父传给孙子辈分的组件就很麻烦 (父->子->孙)
缺点:子组件无法直接修改父组件数据,属单向绑定 - 子组件直接使用父组件的数据,
优点:子组件通过this.$parent.xxx使用父组件的数据
缺点:子组件可直接修改父组件数据 - 依赖注入 provide / inject
优点:这对选项需要一起使用,以允许一个祖先组件向其所有子孙后代注入一个依赖,不论组件层次有多深,并在其上下游关系成立的时间里始终生效。
缺点:不容易定位祖先组件注入位置
后代向父组件传值
- 子组件通过触发事件向父组件传值 $.emit()
- 使用ref属性
- 使用slot插槽方式
兄弟之间组件传值
- eventBus
父组件直接修改子组件的值,子组件直接修改父组件的值
- 父组件修改子组值
<Child ref="setChild"></Child> this.$refs.setChild.xxx = '修改值'
- 子组件直接修改父组件的值
this.$parent.xxx = '修改值'
eventBus示例
初始化时全局定义
// eventBus.js 中
import Vue from 'vue'
// 第一种定义方式
Vue.prototype.$eventBus = new Vue()
// 第二种定义方式
window.eventBus = new Vue();
// 第三种定义方式
export const eventBus = new Vue()
触发事件
//使用方式一定义时
// params 多个参数
this.$eventBus.$emit('eventName', param1,param2,...)
//使用方式二定义时
eventBus.$emit('eventName', param1,param2,...)
监听事件
//使用方式一定义时
this.$eventBus.$on('eventName', (param1,param2,...)=>{
//需要执行 逻辑代码
// params 多个参数
})
//使用方式二定义时
eventBus.$on('eventName', (param1,param2,...)=>{
//需要执行 逻辑代码
})
移除事件
在开发的过程中,我们要及时移除不使用的 eventBus ,原因:
- 为了避免在监听时,事件被反复触发
- 由于热更新,事件可能会被多次绑定监听,这时也需要移除事件监听
- 未及时移除的 eventBus 会导致内存泄漏
this.$eventBus.$off('eventName');
//使用方式二定义时
eventBus.$off('eventName');
//使用方式三定义时
eventBus.$off.$on('eventName');
vue踩坑之eventBus.$on多次触发的问题
this.root.Bus.on
实际是向Bus容器中添加一个事件监听器,当页面跳转时,原来的vue组件被注销,但是原来vue组件向Bus容器中添加的事件监听器并不会被移除。因此,当下次进入这个vue组件对应的页面时,执行到this.root.Bus.on
时,又会向Bus容器中添加一个重复的事件监听器,以此类推,导致Bus容器中有很多个一模一样的事件监听器,从而导致事件只被触发一次,但是回调函数被执行多次的现象。
解决方法:
方法1:在每次on之前调用off卸载掉事件
created(){
eventBus.$off.$on("fetchList",()=>{
this.getListData()
})
}
方法2:在生命周期beforeDestroy
destroyed
里面调用$off卸载掉事件
beforeDestroy(){
eventBus.$off("fetchList")
}
如果这变得重复,你可以写一个mixin来自动化。