技术名称: event bus -- 事件车
场景: 在`头部组件`中点击搜索按钮, 需要把输入框的值传递给`商品组件`
这些组件的共同点: 同一个vue对象管理的, 这些组件中的`this.$root` (root:根源,根) 是同一个对象
Vue对象提供3个方法:
- `$emit('事件名', 参数)`:触发一个事件
- `$on(监听事件名, 回调函数)`:监听指定事件触发
- `$off(监听事件)`: 删除事件的监听
例子:
1、触发事件:
Header.vue头部组件中,点击搜索,触发事件
this.$root.$emit("search_kw", this.kw)
散布消息:this.kw
methods: {
//1、当前不是Products触发跳转,2、如果是Products则触发搜索操作
goProducts() {
console.log("route", this.$route);
if (this.$route.name == "Products") {
//发布消息:搜索操作被触发,值是kw
//$root:所有组件最终会出现在同一个vue对象中,这个vue对象就是根root
//$emit:散布消息
this.$root.$emit("search_kw", this.kw);
} else {
this.$router.push(`/products/${this.kw}`);
}
},
},
2、监听事件:
Products.vue,接收散布过来的消息,然后网络请求获取数据
mounted() {
this.getData(this.kw); //首次切换到当前组件,采用路由中提供的词
//挂载时,监听搜索消息被触发这个消息$emit
this.$root.$on("search_kw", (kw) => {
console.log("搜索操作:", kw);
// this.kw = kw; //收到的消息kw,赋值到本地,好用,但是报错,this代表data,变量与props冲突
this.getData(kw); //调用获取数据的方法
});
},
注意:此处的kw存在变量props中,如果通过this.kw重新赋值,会冲突,所有获取网络数据的时候采用传参的方式
methods: {
getData(kw) {
let url = "product/list.php?pno=1&kw=" + kw;
this.axios.get(url).then((res) => {
console.log(res);
this.data = res.data;
});
},
},
3、删除事件监听:
Products.vue,每次路由切换到当前组件,都会触发挂载方法,就会添加一个新的监听器,应该在组件销毁前删除监听器
beforeDestroy() {
console.log("组件将要销毁,删除监听器search_kw");
//$off(监听的信息):删除监听器
this.$root.$off("search_kw");
},