todo-list案例--全局事件总线

全局事件总线: 一种可以在任意组件间通信的方式,本质上就是一个对象,它需要满足以下条件:
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>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值