vuex-todos
1,创建 stores 文件夹,在其目录下分别创建 state actions mutations getters mutation-types 模块,以及集成这些模块向外暴露 store 对象的 index.js 模块
① index.js
② state.js
2,完成 添加 todo
① mutation-types.js,mutations 常量模块
② actions.js
将 todo 作为包装为一个对象传给 mutataion 时
若直接将 todo 传给 mutation
③ mutations.js
④ 编写完 store 对象,在 main.js 中注册
⑤ 组件中使用 $store 对象的数据
todoHeader.vue
todoList.vue
添加一个 todo 后
3,完成删除 todo
① mutataion-types.js
② actions.js
③ mutations.js
④ todoItem.vue
4,已完成 和 全部 数据渲染
getters.js
是否全选事件完成
① mutation-types.js
② actions.js
③ mutations.js
④ todoFooter.vue
5,清除已完成任务
① mutataion-types
② actions.js
③ mutation.js
④ todoFooter.vue
6,使用 mapState,mapGetters,mapActions 将 store 对象属性映射到 组件对象上。
todoHeader.vue
<template> <div class="todo-header"> <input type="text" placeholder="请输入你的任务名称,按回车键确认" @keyup.enter="handleAdd" v-model="input_todo" /> </div> </template> <script> export default { data: function () { return { input_todo:"" }; }, methods: { handleAdd() { //得到输入的数据 this.input_todo=this.input_todo.trim() //检查合法性 if(!this.input_todo){ alert("请输入"); return; } let todo={ isComplete:false, title:this.input_todo } //PubSub.publish("add", todo); this.$store.dispatch('addTodo',todo) //清空输入框 this.input_todo = ""; }, }, }; </script>
todoList.vue
<template> <ul class="todo-main"> <todoItem v-for="(todo,index) in todos" :key="index" :todo="todo" :index="index"/> </ul> </template> <script> import todoItem from './todoItem' import { mapState } from 'vuex'; export default { computed:{ ...mapState(['todos']) }, components:{ todoItem }, }; </script>
todoItem.vue
<template> <li :style="{background:isShowDel?'#ccc':'#fff'}" @mouseenter="mouseEnter(true)" @mouseleave="mouseEnter(false)"> <label> <input type="checkbox" v-model="todo.isComplete"/> <span>{{todo.title}}</span> </label> <button class="btn btn-danger" v-show="isShowDel" @click="handleDel">删除</button> </li> </template> <script> export default { props:{ todo:Object, index:Number }, data:function(){ return { isShowDel:false, } }, methods:{ mouseEnter(value){ if(value){ //鼠标移入事件 this.isShowDel=true; } else{//鼠标移出事件 this.isShowDel=false } }, handleDel(){ if(window.confirm(`确定删除${this.todo.title}吗`)){ this.$store.dispatch('delTodo',this.index) } } } }; </script>
todoFooter.vue
<template> <div class="todo-footer"> <label> <input type="checkbox" v-model="checkAll"/> </label> <span> <span>已完成{{hasCompleteNum}}</span> / 全部{{totalNum}} </span> <button class="btn btn-danger" v-show="hasCompleteNum" @click="delAllCompleted">清除已完成任务</button> </div> </template> <script> import { mapState, mapGetters } from 'vuex'; export default { computed:{ ...mapGetters(['totalNum','hasCompleteNum']), //控制全选按钮是否选中 checkAll:{ get(){ //是否勾选 return this.hasCompleteNum==this.totalNum&& this.totalNum>0 }, set(value){ //点击全选checkbox,value时当前checkbox的选中状态 this.$store.dispatch('selectAll',value); } } }, methods:{ delAllCompleted(){ if(window.confirm('确定清除已完成的吗?')){ this.$store.dispatch('delAllCompleted') } } } }; </script>