简单的说就是存放一些项目里常用值的地方。如导航菜单,人员信息,地区信息等。
- 该状态值为响应式的,即数值发生变化时所有引用的页面渲染也会发生变化。
关于几个核心概念的简单解释:
- state 数据存储的地方。
- getters 用于帮我们过滤state里的数据。如我们只需要拿state下某个对象的id就可以通过getters实现。
- mutation 我们可以通过commit一个mutation来修改 state 里的值。必须为同步的,防止多地同时修改仓库的值。
- action 用来提交一个mutation 不过是可以异步的。我们可以在axios 调用接口成功后来处理这个数据。通过
store.dispatch()
来触发 - modules 用于数据量过大时,进行数据划分。
1、state官网详解
在组件中,我们可以通过在根实例注册。在计算属性中通过this.$store.state
来访问。
代码示例:
const Counter = {
template: `{{ count }}`,
computed: {
count () {
return this.$store.state.count
}
}
}
为了简化多个状态值引用写法冗余的问题,可以通过mapState
辅助函数来引入。
computed: mapState({
// 箭头函数可使代码更简练
count: state => state.count,
// 传字符串参数 'count' 等同于 `state => state.count`
countAlias: 'count',
// 为了能够使用 `this` 获取局部状态,必须使用常规函数
countPlusLocalState (state) {
return state.count + this.localCount
}
})
key,value相同时,可以传一个数组:
computed: mapState([
// 映射 this.count 为 store.state.count
'count'
])
2、getters详解
接收第一个参数为state,可以接收第二个参数。
const store = new Vuex.Store({
state: {
todos: [
{ id: 1, text: '...', done: true },
{ id: 2, text: '...', done: false }
]
},
getters: {
doneTodos: state => {
return state.todos.filter(todo => todo.done)
}
}
})
可以调用其他getter:
getters: {
// ...
doneTodosCount: (state, getters) => {
return getters.doneTodos.length
}
}
同样的,处理批量可以用mapGetters:
computed: {
// 使用对象展开运算符将 getter 混入 computed 对象中
...mapGetters([
'doneTodosCount',
'anotherGetter',
// ...
])
}
3、mutation详解
- 可以接收参数,对象
mutations: {
increment (state, payload) {
state.count += payload.amount
}
}
4、action详解
常用于 axios 请求接口后处理数据。例如购物车:
actions: {
checkout ({ commit, state }, products) {
// 把当前购物车的物品备份起来
const savedCartItems = [...state.cart.added]
// 发出结账请求,然后乐观地清空购物车
commit(types.CHECKOUT_REQUEST)
// 购物 API 接受一个成功回调和一个失败回调
shop.buyProducts(
products,
// 成功操作
() => commit(types.CHECKOUT_SUCCESS),
// 失败操作
() => commit(types.CHECKOUT_FAILURE, savedCartItems)
)
}
}
在组件中分发action:
import { mapActions } from 'vuex'
export default {
// ...
methods: {
...mapActions([
'increment', // 将 `this.increment()` 映射为 `this.$store.dispatch('increment')`
// `mapActions` 也支持载荷:
'incrementBy' // 将 `this.incrementBy(amount)` 映射为 `this.$store.dispatch('incrementBy', amount)`
]),
...mapActions({
add: 'increment' // 将 `this.add()` 映射为 `this.$store.dispatch('increment')`
})
}
}
多个action之前调用可以通过 async/await来实现:
// 假设 getData() 和 getOtherData() 返回的是 Promise
actions: {
async actionA ({ commit }) {
commit('gotData', await getData())
},
async actionB ({ dispatch, commit }) {
await dispatch('actionA') // 等待 actionA 完成
commit('gotOtherData', await getOtherData())
}
}