几分钟搞懂Vuex(State,Mutations,Actions)

3,362 阅读2分钟

「这是我参与11月更文挑战的第19天,活动详情查看:2021最后一次更文挑战

在这里插入图片描述 这是Vuex官方给出的图片,看起来有点不好理解,上详解!!!! 开始介绍之前,我们需要将Vuex挂载到Vue实例上面,这样我们才能在Vue的所有组件中都可以使用这些数据,这里我们store文件夹下面的index.js存放我们的Vuex代码。 记得在入口文件main.js里面导入store对象

State

暂时可以将他看作是data中的属性,也就是我们当前的状态。 state里面的这些属性都会被加入到响应式系统里面,而响应式系统会监听属性的变化,一旦属性发生变化,会通知所有用到这个属性的界面并进行刷新。 但有一个前提,所有的属性都必须先初始化好,如果直接在mutations里面添加一个新的属性,界面是不会显示的。

//Vuex
const store = new Vuex.Store({
	sate:{
		count: 0
	},
	mutations:{
		increament(state){
		state.count ++
		},
		decreament(state){
		state.count --
		}
	}
})


//App.vue
<template>
	<div id="app">
		<p>{{count}}</p>
		<button @click="increment">+1</button>
		<button @ click="decrement">-1</button>
	</div>
</template>
<script>
export default {
	name:' App', 
	components:{
	}, 
	computed:{
		count: function(){
		 //可以通过$this.$store.sate访问Vuex里面state的状态
			return this. $store.state.count 
	}
},
	methods:{
		increment: function ){
		//通过this.Store.commit(mutations中的方法)来修改状态
			this. Sstore. commit(' increment')
		}, 
		decrement: function ){
			this. Sstore. commit(' decrement')
		}

Getters

有时候我们需要获取一些state变异后的状态,就需要使用到我们的Getters了,有点类似于我们的computed计算属性

  1. 我们想要获取students数组里面年龄大于20的数据,我们可以适应computed属性获取,但是我们想要在多个页面获取变化后的数据,就需要在每一个组件里面都添加一个计算属性,效率极低!!!Getters该出场了!!!!
//Vuex
const store = new Vuex.Store({
	sate:{
		students:[
			{id:110,name:'zhangsan',age:18},
			{id:111,name:'lisi',age:21},
			{id:112,name:'wangwu',age:25},
		]
	},
	getters:{
	//这样我们就获取到了年龄大于20的数据,在需要的组件直接展示即可
		getmore20:state => 
			return state.students.filter(s => s.age > 20)
	}
})


  1. getters默认是不能传递参数的,如果我们希望她能传递一个参数,我们只能让getters本身返回另一个函数 我们想要获取年龄大于20的个数
//Vuex
getters:{
		//1.我们可以直接添加length:{{getmore20.length}}获取
		getmore20(state){
			return state.students.filter(s => s.age > 20)
			}
		//2.将getters作为一个参数传递
		getmore20Len(state,getters){
			return getters.getmore20.length
			}
		//3.我们自定义在组件展示的地方传入一个年龄比如<h2>{{getmoreAge(30)}}</h2>
		//这里我们想要自定义获取一个年龄大于30的数据
		getmoreAge(state){
			return function(age){
				return state.students.filter(s => s.age >= age)
			}
		}
	}

Mutation

在State里面已经大概了解了Mutations是什么,但是还有很多细节部分

  1. Vuex官方明确:store里面state状态更新的唯一方式就是通过提交Mutations 2.mutations主要包含两部分:事件类型回调函数 mutations里面的方法必须是同步的,异步用actions
mutations:{
	increament(state){
		state.count ++
	},
}
//这里的increament被称为时间类型,其余被称为回调函数,state是回调函数的第一个参数

//mutations更新的方式就是上文提到的通过this.$store.commit的方式
  1. 当我们需要点击按钮进行数据的+5或者+10 的时候,我们可以自己传入5或者10的参数进行展示。
//App.vue
<button @click="addFive(5)">+5</button>

methods:{
//1.第一种提交风格,count是一个数字
	addFive(count){
		this.$store.commit('addCount',count)
	}
	//第二种提交风格,payload是一个对象
	addFive(count){
		this.$store.commit({
			type: 'addCount',
			count: 5
	})
	}
}


//Vuex
mutation:{
    //1.第一种提交风格
	addCount(state,count){
		state.counter += count
	}
	//第二种提交风格
	addCount(state,payload){
		state.counter += payload.count
	}
}
  1. 向students里面再添加一个学生信息,我们在更新数据的时候,我们可能希望携带一些额外的参数(stu),这个参数被称为mutations的载荷(payload)
//App.vue
<button @click="addStudents">+5</button>

methods:{
	addStudents(){
		const stu = {id:115,name:'kobe',age:40}
		this.$store.commit('addStu',stu)
	}
}


//Vuex
mutation:{
	addStu(state,stu){
		state.students.push(stu)
	}
}
  1. 添加和删除非响应式数据
//App.vue
 <h2>{{$store.state.info}}</h2>
    <button @click="updateInfo">修改信息</button>

methods:{
 updateInfo() {
 	this.$store.commit('updateInfo')
 	}
}


//Vuex
state:{
	info: {
      name: '张三',
      age: 40,
      height: 180
    }
}
updateInfo(state) {
    // state.info.address='湖南'  //无效,做不到响应式
    Vue.set(state.info, 'address', '湖南')
    // delete state.info.name   //无效,做不到响应式
    Vue.delete(state.info, 'height')
  }

Actions

actions类似于mutations,但是是用来代替muations进行异步操作的

  1. 点击按钮之后过一段时间在执行
//Vuex
 state :{
  counter: 1000,
}

mutations:{
	increment(state){
		state.counter ++
	}
}
actions:{
 increament(context){
 //context:上下文,这里可以理解为store对象
 	setTimeOut(()=>{
		context.commit('increment')
	},1000)
	}
}


//App.vue
 <h2>{{counter}}</h2>
<button @click="increment">异步修改</button>

methods:{
	increment(){
		this.$store.dispath('increament')//给actions发出一个自定义事件
	}
}
  1. actions返回的Promise
//Vuex
 state :{
  counter: 1000,
}

mutations:{
	increment(state){
		state.counter ++
	}
}
actions:{
 increament(context){
	return new Promise((resolve)=>{
 		setTimeOut(()=>{
			context.commit('increment')
			resolve()
		},1000)
	  }
	})
}


//App.vue
 <h2>{{counter}}</h2>
<button @click="increment">异步修改</button>

methods:{
	increment(){
		this.$store.dispath('increament').then(res=>{
			console.log('完成了更新')
		})
	}
}