全局事件总线
案例

根据图中的信息:需要接收的组件绑定事件,并且执行回调函数,而发送信息的组件,控制事件发生以及将信息发送到对应组件
Student组件,接收信息
<template>
<div class="demo"></div>
</template>
<script>
export default {
name: "StudentList",
methods: {},
mounted() {
this.$bus.$on("send", (data) => {
//接收信息,并打印输出
console.log("兄弟组件收到信息", data);
});
},
beforeDestroy() {
//每次销毁前都将事件解绑,不占用事件名
this.$bus.$off("send");
},
};
</script>
Family组件,发送信息
<template>
<div class="demo">
<h2>姓名:{{ name }}</h2>
<h2>角色:{{ character }}</h2>
<button @click="sendName">传递数值</button>
</div>
</template>
<script>
export default {
name: "FamilyList",
data() {
return {
name: "野原广志",
character: "father",
};
},
methods: {
sendName() {
//事件触发,传递信息
this.$bus.$emit("send", this.name);
},
},
};
</script>
需要在main.js内配置相应的$bus
import Vue from 'vue'
import App from './App.vue'
Vue.config.productionTip = false
new Vue({
render: h => h(App),
beforeCreate() {
// 在Vue的原型对象上添加个$bus
Vue.prototype.$bus = this
}
}).$mount('#app')
todolist修改
与案例中的类似,修改为用事先定义的$bus即可,这里关系为,App的孙子组件为MyItem,实现两者的通信,则需要利用$bus
MyItem
<template>
<li>
<label>
<!-- 如下代码也能实现功能,但是不太推荐,因为有点违反原则,因为修改了props -->
<!-- <input type="checkbox" v-model="todo.done"/> -->
<input
type="checkbox"
:checked="inser.done"
@change="handleCheck(inser.id)"
/>
<span>{{ inser.title }}</span>
</label>
<button class="btn btn-danger" @click="handleDelete(inser.id)">删除</button>
</li>
</template>
<script>
export default {
name: "MyItem",
props: ["inser"],
methods: {
handleCheck(id) {
this.$bus.$emit("checkTodo", id);
},
handleDelete(id) {
this.$bus.$emit("deleteTodo", id);
},
},
};
</script>
App
<template>
<div id="root">
<div class="todo-container">
<div class="todo-wrap">
<MyHeader @addTodo="addTodo" />
<MyList
:todos="todos"
:checkTodo="checkTodo"
:deleteTodo="deleteTodo"
/>
<MyFooter
:todos="todos"
@checkAllTodo="checkAllTodo"
@clearAllTodo="clearAllTodo"
/>
</div>
</div>
</div>
</template>
<script>
import MyHeader from "./components/MyHeader";
import MyList from "./components/MyList";
import MyFooter from "./components/MyFooter.vue";
export default {
name: "App",
data() {
return {
// 由于todos是MyHeader组件和MyFooter组件都在使用,所以放在App中(状态提升)
todos: JSON.parse(localStorage.getItem("todos")) || [],
};
},
methods: {
addTodo(todoObj) {
this.todos.push(todoObj);
},
checkTodo(id) {
this.todos.forEach((todo) => {
if (todo.id === id) todo.done = !todo.done;
});
},
deleteTodo(id) {
if (confirm("确认删除吗?"))
this.todos = this.todos.filter((todo) => todo.id !== id);
},
checkAllTodo(done) {
this.todos.forEach((todo) => {
todo.done = done;
});
},
clearAllTodo() {
this.todos = this.todos.filter((todo) => {
return !todo.done;
});
},
},
mounted() {
this.$bus.$on("checkTodo", this.checkTodo);
this.$bus.$on("deleteTodo", this.deleteTodo);
},
watch: {
todos: {
deep: true,
handler(value) {
localStorage.setItem("todos", JSON.stringify(value));
},
},
},
components: { MyHeader, MyList, MyFooter },
};
</script>
运行结果

其中by root的就是通过总线来实现通信的,而其他则表示用的是其他方法。
如果是父传子则用props比较方便,子传父也有之前提及的方法。
128

被折叠的 条评论
为什么被折叠?



