一、什么是Vuex
官网:Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。Vuex 也集成到 Vue 的官方调试工具 devtools extension ,提供了诸如零配置的 time-travel 调试、状态快照导入导出等高级调试功能。
通俗的来说,vuex是用于当某一状态需要在多个组件中共享,方便我们使用并追踪这些状态时使用。
二、Vuex的基本结构
1、安装vuex,创建store文件夹并新建index.js文件,写入:
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const store = new Vuex.Store({
state: {
},
getters: {
},
mutations: {
},
actions: {
},
modules: {
}
})
export default store
2、在main.js中导入,并挂载到Vue实例当中去
三、State详解
1、Vuex采用的是单一状态树模式(SSOT,simple source of truth),这个意味着在vuex中有且仅有一个实例,所有的数据都集中一个实例中,方便我们访问。
2、如果我们在state中定义一个counter,那么在多个组件中均可访问到这个counter
state: {
counter:1000
},
//在组件中访问
computed:{
count() {
return this.$store.state.counter
}
},
四、Getter详解
1、Vuex 允许我们在 store 中定义“getter”(可以认为是 store 的计算属性)。就像计算属性一样,getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。
state: {
students:[
{id: 1,name: 'wsh',score: 98},
{id: 2,name: 'yj',score: 97},
{id: 3,name: 'lisi',score: 87},
{id: 4,name: 'zhangs',score: 89}
]
},
getters: {
goodStu(state){
return state.students.filter(item => item.score>=90)
}
},
2、Getter 会暴露为 store.getters 对象,我们可以通过属性的形式访问这些值:
//获取得分大于等于90的学生
<p>{{$store.getters.goodStu}}</p>
3、Getter 也可以接受其他 getter 作为第二个参数:
//获取得分大于等于90的学生的个数
getters: {
goodStu(state){
return state.students.filter(item => item.score>=90)
},
goodStuNum(state,getters){
return getters.goodStu.length
}
},
<p>{{$store.getters.goodStuNum}}</p>
4、给 Getter 传参,例如获取得分高于参数 score 的学生
moreScore(state){
return function(score){
return state.students.filter(item => item.score>=score)
}
}
//分数大于等于88的学生
<p>{{$store.getters.moreScore(88)}}</p>
五、Mutation详解
1、更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。Vuex 中的 mutation 非常类似于事件:每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数:
mutations: {
increment(state){
state.counter++
},
decrement(state){
state.counter--
}
},
2、调用store.commit方法来唤醒这个回调函数
methods:{
add(){
this.$store.commit('increment')
},
sub(){
this.$store.commit('decrement')
}
}
2、我们可以向 store.commit 传入额外的参数,即 mutation 的 载荷(payload),在大多数情况下,载荷应该是一个对象,这样可以包含多个字段并且记录的 mutation 会更易读:
//mutations中
addStu(state,payload){
state.students.push(payload)
}
//methods中
addStu(){
this.$store.commit('addStu',{id: 5,name: 'kobe',score: 95})
}
3、提交 mutation 的另一种方式是直接使用包含 type 属性的对象:
//其中amount通过payload.amount取出
store.commit({
type: 'increment',
amount: 10
})
4、Mutation 需遵守 Vue 的响应规则: ①最好提前在你的 store 中初始化好所有所需属性。 ②当需要在对象上添加新属性时,我们应该使用 Vue.set (state.obj, ‘newProp’, 123) 。③当需要在对象上删除某属性时,我们同样不能直接使用delete方法,而是应该使用 Vue.delete (state.obj,‘oldProp’) 。
5、使用常量替代 Mutation 事件类型。在多人协助的大型项目中会很有帮助,可自行学习。
六、Action详解
1、首先,action主要是用于进行一些异步操作的,因为如果在mutation中进行异步操作会导致无法跟踪的问题,所以所有的异步操作都建议放到action当中去执行,但是需要注意,只要我们需要修改状态,那么都必须通过mutation。
//Action函数接受一个与 store 实例具有相同方法和属性的 context 对象
actions: {
updateInfo(context){
setTimeout(() => {
context.commit('changeInfo')
},2000)
}
},
//在mutations中
changeInfo(state){
state.kobe.age = 99
}
//在methods中,通过store.dispatch方法来触发Action函数
change(){
this.$store.dispatch('updateInfo')
}
2、action同样支持payload载荷来传入参数
change(){
this.$store.dispatch('updateInfo',{})
}
3、如果我们想知道何时结束这个异步操作,我们可以返回一个Promise:
actions: {
updateInfo(context){
return new Promise((resolve,reject) => {
setTimeout(() => {
context.commit('changeInfo')
resolve("some message")
},2000)
})
}
},
change(){
this.$store.dispatch('updateInfo').then(res => {
console.log(res);
})
}
七、Module详解
1、由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。为了解决以上问题,Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割:
const moduleA = {
state:{
birthday: 1999
},
getters:{
fullBirth(state){
return state.birthday + "01"
},
fullBirth1(state,getters){
return getters.fullBirth + "10"
},
fullBirth2(state,getters,rootState){
return getters.fullBirth1 + rootState.blessing
}
},
mutations:{
changeBirth(state,payload){
state.birthday = "2000"
}
},
actions:{
updateBirth(context){
setTimeout(() => {
context.commit('changeBirth',{})
},1000)
}
}
}
//在store实例中
modules: {
a: moduleA
}
2、state :通过store.state.a可以直接获取a模块的状态,这是因为a会被放入到store实例的state当中去:
<h2>{{$store.state.a.birthday}}</h2>
3、getter:子模块中的getters可以拥有第三个参数rootState用于获取根状态,使用如下
<h2>{{$store.getters.fullBirth}}</h2>
<h2>{{$store.getters.fullBirth1}}</h2>
<h2>{{$store.getters.fullBirth2}}</h2>
4、mutation:同样是通过store.commit提交:
this.$store.commit('changeBirth')
5、action:同样通过store.dispatch提交:
this.$store.dispatch('updateBirth')
八、总结
以上就是vuex的五大核心模块,还有一些细节可能并不完善,大家可以去官网进一步学习,如有错误欢迎大家指正。
官网指路