vuex实现简单的todoList

首先新建一个vue项目,然后install vuex。
在建好的项目中,首先在src文件夹下新建一个store.js,当然,如果你比较追求完美,可以新建一个store文件夹,里面再创建一个js,store.js文件中,首先需要引入vue和vuex,然后再将vuex全局注入到vue中,就想这样:

import Vue from 'vue';
import Vuex from 'vuex'
// vuex注入到vue中
Vue.use(Vuex);

然后新建一个仓库:

 export default new Vuex.Store({})

在仓库中先写好state,mutations,actions,getters和setters,就是vuex的全家桶,state中存放需要进行计算和操作的数据

state:{ //存放需要进行计算和操作的数据
	count:0, //数量
	todoList:[ //正在进行中的事件以及是否完成
	{todo:"吃饭",isComplete:false},
	{todo:"睡觉",isComplete:false},
	{todo:"打豆豆",isComplete:true},
	]
		
	},

对了,还需要注意的是,你需要将store,在入口文件main.js中引入,一定要记得加上这一步:

import Vue from 'vue'
import App from './App'
import router from './router'
import store from './store'
Vue.config.productionTip = false

/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
	store,
  components: { App },
  template: '<App/>'
})

ok,再回来,我们在state中定义好数据以后,在components文件夹下新建一个vue文件,todoList,然后写上列表样式,就是未完成的部分的列表:

<template>
	<div>
		<Input/>
		<ul>
			<!-- 显示未完成的 -->
			<li v-for="(todo,index) in todoList" :key="index">
				<input type="checkbox"/>
				<span>{{todo.todo}}<button @click="del(todo)">删除</button></span>
			</li>
		</ul>
		<complete></complete>
	</div>
</template>
<script>

记得在style样式中加上

ul{
		list-style:none;
		margin:0;
		}

去掉小点。
然后再新建一个vue文件,将todoList引入,展示出来,就是说新建的vue文件是todoList的父组件。
todoList中的v-for循环中的todo是从store中获取的,用辅助函数去获取,首先引入辅助函数

import {mapState,mapActions} from 'vuex'
computed:{
			//返回一个对象(展开运算符的效果)
			// count(){
			// 	return count
			// }
			// 当计算属性名和state属性名一致的时候,传数组
			// ...mapState(["todoList","count"])
			...mapState({  //计算属性的名字和state里面属性的名字不一样
				count:"count", //字符串代表你传给后台的state里面的值
				todoList:"todoList"
			})
		},

接下来就是写完成部分,创建一个vue文件isComplete,然后作为todoList的子组件引入todoList。
在isComplete文件中,首先我们需要获取到完成的事件,那么就要在store.js中的getters中写个方法,让它过滤掉未完成的事情。
getters相当于store的计算属性,只有当它的依赖改变之后,才会触发此函数,而它的依赖就是state,看代码:

getters:{//相当于store的计算属性,只有当他的依赖改变之后才会触发此函数
		complete(state,getters){ //state就是它的依赖
			// console.log(state)
			//过滤掉未完成的,返回已经完成的项
			return state.todoList.filter(item => item.isComplete!==false)
		},
	}

那么,接下来我就可以在isComplete.vue这个文件下,v-for li,看代码:

<template>
	<div>
		<h1>已完成的选项</h1>
		<ul>
			<li v-for="(item,index) in complete" :key="index">{{item.todo}} <button @click="del(item)">删除</button></li>
		</ul>
	</div>
</template>

为什么给个index呢,是为了之后的删除,这个等下再讲。之后我们在isComplete.vue这个文件下,引入mapGetters辅助函数:

import {mapGetters} from "vuex"
	export default{
		computed:{
			...mapGetters([
				"complete"
			])
		},
		}
	

接下来我们做输入选项的部分,因为todoList本来就类似于记事本,输入内容,将内容添加到下面的列表中。ok,我们来创建一个vue文件,取名为input,简单明了,input是和isComplete一样,作为todoList的子组件,所以我们把它引入todoList。然后,我们写input的样式,代码:

<template>
	<div>
		<input type="text" v-model="todo" >
		<button @click="add(todo)">添加</button>
	</div>
</template>

add方法中的todo参数,是我在data中自己定义的一个字符串,然后再methods中写add这个方法,
add这个方法是为了触发mutation中的方法,我在store中的mutation下写下add方法,代码如下:

add(state,payload){ //载荷是数据
			let item = JSON.parse(payload)
			state.todoList.push(item)	
		},

至于为什么要把payload转换成JSON对象呢,等下说。
mutation中的事件需要actions来提交,所以,我们在actions中写上addItem的方法,用来提交mutation中的方法,代码如下:

actions:{ //异步执行mutation的方法
		addItem({commit},payload){
			let todoItem = {
				todo:payload, //携带的数据
				isComplete:false
			};
			todoItem = JSON.stringify(todoItem) 
			console.log(payload)
			// commit('add',payload)//此处不要漏写了mutation里面的方法
		     commit('add',todoItem)	 
		},

由于action传递的参数只能是字符串,所以只能把对象转成字符串,至于commit,你console.log一下store,就能看到,这是actions的属性之一。所以,mutation中的方法需要将JSON字符串转换成JSON对象追加到state的todoList对象中。然后我们来做个功能表,就是说每当你添加一条数据,点击添加按钮的时候,输入框中的内容都会被清空,代码如下:

add(todo){
				this.todo="";
				console.log(222);
				this.addItem(todo);
			},
			...mapActions(["addItem"])

我们先是通过mapActions来提交mutations中的方法,然后因为每次添加都要清空嘛,所以,我在add这个方法中先每次清空掉输入框中的内容,然后,调用一次addItem ,l里面传上参数todo。
接下来写删除。
同样,在mutations中写下del方法,然后在actions中写一个方法去提交它,代码如下:

del(state,index){
			console.log(index);
			state.todoList.splice(index,1);
		}
handleDel({commit,state},item){
			// 获取下标
			let list=[],
			cindex=null;
			state.todoList.map((i,index)=>{//为了获取到下标,因为要通过下标来删除对应的事件
				if(i.todo===item.todo){
					cindex=index;
				}
			})
			commit('del',cindex)//此处不要漏写mutation里面的方法
		}

在TodoList中,我们通过dispatch来触发store中Actions中的删除方法,代码如下:

del(item){
				this.$store.dispatch("handleDel",item)
			}

完整代码:
store.js

import Vue from 'vue';
import Vuex from 'vuex'
// vuex注入到vue中
Vue.use(Vuex);

 export default new Vuex.Store({ //仓库
	state:{ //存放需要进行计算和操作的数据
	count:0, //数量
	todoList:[ //正在进行中的事件以及是否完成
	{todo:"吃饭",isComplete:false},
	{todo:"睡觉",isComplete:false},
	{todo:"打豆豆",isComplete:true},
	]
		
	},
	// 需求:返回已经完成的选项
	// 怎么做:1.需要一个方法来返回已经完成的选项并且让部分子组件得到
	// mutation中写需要操作的方法,由commit触发,mutation是同步的
	mutations:{
		add(state,payload){ //载荷是数据
			let item = JSON.parse(payload)
			state.todoList.push(item)
			
		},
		del(state,index){
			console.log(index);
			state.todoList.splice(index,1);
		}
		
	},
	actions:{ //异步执行mutation的方法
		addItem({commit},payload){
			let todoItem = {
				todo:payload,
				isComplete:false
			};
			todoItem = JSON.stringify(todoItem)
			console.log(payload)
			// commit('add',payload)//此处不要漏写了mutation里面的方法
		     commit('add',todoItem)
			 console.log(1111);
			 
		},
		handleDel({commit,state},item){
			// 获取下标
			let list=[],
			cindex=null;
			state.todoList.map((i,index)=>{
				if(i.todo===item.todo){
					cindex=index;
				}
			})
			commit('del',cindex)//此处不要漏写mutation里面的方法
		}
		
	},
	getters:{//相当于store的计算属性,只有当他的依赖改变之后才会触发此函数
		complete(state,getters){ //state就是它的依赖
			// console.log(state)
			//返回已经完成的项
			return state.todoList.filter(item => item.isComplete!==false)
		},
		// 如果要接受参数,那么需要返回一个函数
		// test:function(state){
		// 	return function(val){
		// 		return state.count + val
		// 	}
		// },
		test:state => val =>state.count+val
		
	}
})

view.vue

<template>
	<div>
		<h1>ToDoList</h1>
		<todoList></todoList>
	</div>
</template>

<script>
	import todoList from '@/components/HelloWorld.vue'
	// 注册
	export default {
		components:{
			todoList
		},
		
	}
</script>

<style scoped>
</style>

todoList.vue

<template>
	<div>
		<Input/>
		<ul>
			<!-- 显示未完成的 -->
			<li v-if="!todo.isComplete" v-for="(todo,index) in todoList" :key="index">
				<input type="checkbox" v-model="todo.isComplete"/><!--因为点击勾选就是已完成,不选就是未完成,也可通过mutation写方法来改变状态-->
				<span>{{todo.todo}}<button @click="del(todo)">删除</button></span>
			</li>
		</ul>
		<complete></complete>
	</div>
</template>
<script>
	//通过辅助函数
	import {mapState,mapActions} from 'vuex';
	
	import complete from './isComplete.vue'
	import Input from './input.vue'
	export default{
		components:{
			complete,
			Input
		},
		// data(){
		// 	return{
		// 		todoList:this.$store.state.todoList //这边一定是从store中获取的 
		// 	}
		// },
		computed:{
			//返回一个对象(展开运算符的效果)
			// count(){
			// 	return count
			// }
			// 当计算属性名和state属性名一致的时候,传数组
			// ...mapState(["todoList","count"])
			...mapState({  //计算属性的名字和state里面属性的名字不一样
				count:"count", //字符串代表你传给后台的state里面的值
				todoList:"todoList"
			})
		},
		methods:{
			// del(index){
			// 	this.$store.dispatch("handleDel",index)
			// 	
			// }
		del(index){
			this.$store.dispatch("handleDel",index)
		}
		}
		
		
	}
</script>
<style scoped>
	ul{
		list-style:none;
		margin:0;
		}
</style>

isComplete.vue

<!-- 已完成的 -->
<template>
	<div>
		<h1>已完成的选项</h1>
		<ul>
			
			<li v-for="(item,index) in complete" :key="index">{{item.todo}} <button @click="del(item)">删除</button></li>
			
			
		</ul>
	</div>
</template>

<script>
	import {mapGetters,mapActions} from "vuex"
	export default{
		data(){
			return{
				
				
			}
			
		},
		computed:{
			...mapGetters([
				"complete"
			])
		},
		methods:{
			del(item){
				this.$store.dispatch("handleDel",item)
			}
			
			// del(index){
			// 	this.$store.dispatch("handleDel","complete")
			// }
			},
		mounted(){
			
			// let complete = this.$store.getters.complete;
			// console.log(complete)
		}
		}
	
</script>

<style>
</style>

input.vue

<template>
	<div>
		<input type="text" v-model="todo" >
		<button @click="add(todo)">添加</button>
	</div>
</template>

<script>
	import { mapActions } from "vuex";
	export default {
	    data(){
		return{  //输入框输入的
			todo:"",
		}
	},
		methods:{
			
			// add(){  
			// 		let todoItem={
			// 			todo:this.todo,
			// 			isComplete:false
			// 		}
			// 		//由于action传递的参数只能是字符串,所以只能把对象转成字符串
			// 	todoItem = JSON.stringify(todoItem);
			// 	this.$store.dispatch("addItem",todoItem)
			// 	this.todo = ""
			// 	
			// },
			add(todo){
				this.todo="";
				console.log(222);
				this.addItem(todo);
			},
			...mapActions(["addItem"])
			
			 
			//把todoItem传递到mutation
			//dispatch是 调用actions的方法,第一个值是actions的方法,第二个是带过去的值
		
	},
	}
</script>

<style>
</style>

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值