一 概述
1.vuex是做什么的
管理共享状态
现在有两个页面 A 和 B,还有以下两个要求:
要求它们都能对 count 进行操控。
要求 A 修改了 count 后,B 要第一时间知道,B 修改后,A 也要第一时间知道。
把数据源 count 剥离开来,用一个全局变量或者全局单例的模式进行管理,这样不就在任何页面都可以很容易的取到这个状态了。就是 Vuex 的工作。
2.安装vuex
具体看官方文档就可以:
3.如何使用vuex
当我们的项目不大时,可以使用vuex的简单模式–store模式。
4.vuex和全局对象的对比
- Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新。
- 你不能直接改变 store 中的状态。改变 store 中状态的唯一途径就是显式地提交 (commit) mutation。这样使得我们可以方便地跟踪每一个状态的变化,从而让我们能够实现一些工具帮助我们更好地了解我们的应用。
5.vuex组成
Vuex 的内脏由五部分组成:State、Getter、Mutation、Action 和 Module。在实际应用中,这五个部分并不是必须的,你需要用到什么就添加什么。但是一般再怎么简单的 Vuex,也至少会由 State 和 Mutation 构成。
二 State
三 Getter
有时候,我们会发现 State 中的数据,并不是我们直接想要的,如果我们在使用的地方进行处理,那每个使用的地方都需要做改变。这里我们就可以使用getter。
就像计算属性一样,getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。
const store = new Vuex.Store({
state: {
date: new Date()
},
getters: {
// Getter 接受 state 作为其第一个参数
weekDate: state => {
return moment(state.date).format('dddd');
}
}
})
另外,Getter 还会将 store.getters 对象暴露出去,你可以以属性的形式访问这些值:
console.log(store.getters.weekDate)
我们可以很容易地在任何组件中使用它:
computed: {
weekDate () {
return this.$store.getters.weekDate
}
}
现在需求又变了,每个模块要显示的 weekDate 的格式不一样,有的显示全部日期,有的需要显示星期几,怎么办?
因为 weekDate 并不是一个函数,它仅仅只是一个属性而已。我们就想办法把这个属性变成一个函数:
getters: {
// 返回一个函数,就可以传参了
weekDate: (state) => (fm) => {
return moment(state.date).format(fm ? fm : 'dddd');
}
}
具体使用:
store.getters.weekDate('MM Do YY')
四 Mutation
更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。mutations必须是同步函数
const store = new Vuex.Store({
state: {
count: 1
},
mutations: {
// 事件类型 type 为 increment
increment (state) {
// 变更状态
state.count++
}
}
})
注意,我们不能直接 store.mutations.increment() 来调用,Vuex 规定必须使用 store.commit 来触发对应 type 的方法:
store.commit('increment')
我们还可以向 store.commit 传入额外的参数:
mutations: {
increment (state, n) {
state.count += n
}
}
// 调用
store.commit('increment', 10)
这个参数就叫做载荷,在大多数情况下,载荷是一个对象。提交的方式有两种:
// 1、把载荷和type分开提交
store.commit('increment', {
amount: 10
})
// 2、整个对象都作为载荷传给 mutation 函数
store.commit({
type: 'increment',
amount: 10
})
当我们要修改state里面对象:
const store = new Vuex.Store({
state: {
student: {
name: '小明',
sex: '女'
}
}
})
这个时候,我们如果想要给 student 添加一个年龄 age: 18 属性,怎么办呢?
mutations: {
addAge (state) {
Vue.set(state.student, 'age', 18)
// 或者:
// state.student = { ...state.student, age: 18 }
}
}
五 Action
上面的mutations必须是同步函数,如果我们需要使用异步,就轮到Action上场了。
Action与mutations不同之处在于:
- Action 提交的是 mutation,而不是直接变更状态。
- Action 可以包含任意异步操作。
我们首先来看一个Action示例:
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment (state) {
state.count++
}
},
actions: {
increment (context) {
context.commit('increment')
}
}
})
我们也可以通过ES2015的参数表达结构来写: