全局事件总线: 一种可以在任意组件间通信的方式,本质上就是一个对象,它需要满足以下条件:
1. 所有组件对象都要能看的见他
2. 这个对象必须能够使用 $on, $emit, $off 方法去绑定、触发、和解绑事件
使用步骤:
1. 定义全局事件总线
src/main.js
import Vue from 'vue'
import App from './App.vue'
Vue.config.productionTip = false
new Vue({
el: '#app',
render: h => h(App),
beforeCreate() {
//安装全局事件总线
Vue.prototype.$bus = this
}
})
2. 使用事件总线
src/App.vue
<template>
<div id="root">
<div class="toto-container">
<div class="todo-wrap">
<MyHeader @addTodo="addTodo"/>
<MyList :todos="todos"/>
<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'
export default {
name: 'App',
components: {
MyHeader,
MyList,
MyFooter
},
data(){
return{
todos:JSON.parse(localStorage.getItem('todos')) || []
}
},
methods:{
//添加一个todo
addTodo(todo) {
this.todos.unshift(todo)
},
//勾选或取消勾选一个todo
checkTodo(id) {
this.todos.forEach((todo)=> {
if(todo.id === id) {
todo.done = !todo.done
}
})
},
//删除一个todo
deleteTodo(id) {
this.todos = this.todos.filter((todo)=> {
return todo.id !== todo.id
})
},
//全选 or 取消全选
checkAllTodo(done) {
this.todos.foreach((todo)=> {
return todo.done = done
})
},
//清除所有已完成的todo
clearAllTodo() {
this.todos = this.todos.filter((todo)=>{
return !todo.done
})
}
},
watch() {
todos:{
deep:true,
handler(value){
localStorage.setItem('todos',JSON.stingify(value))
}
}
},
//接收数据: A组件想要接收数据,则在A组件中给$bus绑定自定义事件,事件的回调留在A组件自身
mounted() {
this.$bus.$on('checkTodo',this.checkTodo)
this.$bus.$on('deleteTodo',this.deleteTodo)
},
//最好在beforeDestroy钩子中,用$off()去解绑当前组件的所用到的事件
beforeDestroy() {
this.$bus.$off('checkTodo')
this.$bus.$off('deleteTodo')
}
}
</script>
src/components/MyItem
<template>
<li>
<label>
<input
type="checkbox"
:checked="todoObj.done"
@change="handleCheck(todoObj.id)"
/>
<span>{{ todoObj.title }}</span>
</label>
<button class="btn btn-danger" @click="handleDelete(todoObj.id)">删除</button>
</li>
</template>
<script>
export default {
name:'MyItem',
data() {
return {
}
},
props:['todoObj'],
methods:{
handleCheck(id) {
//提供数据:this.$bus.$emit('xxx',data)
this.$bus.$emit('checkTodo',id)
},
handleDelete(id) {
if(confirm('确定删除吗?')) {
//提供数据:this.$bus.$emit('xxx',data)
this.$bus.$emit('deleteTodo',id)
}
}
}
}
</script>