vuex是什么?
“Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。” -----援引自 vuex官网
一、安装
npm install vuex --save
二、核心概念
state:单一状态树,用一个对象就包含了全部的应用层级状态。
Mutation:更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。Vuex 中的 mutation 非常类似于事件:每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数,第二个参数为传入的值:
const store = new Vuex.Store({
state: {
value: 1
},
mutations: {
increment (state, newVal) {
// 变更状态
state.value = newVal
}
}
})
Action:
Action 类似于 mutation,不同在于:
- Action 提交的是 mutation,而不是直接变更状态。
- Action 可以包含任意异步操作。
第一个参数为context对象,第二个参数为传入参数:
const store = new Vuex.Store({
state: {
value: 1
},
mutations: {
increment (state, newVal) {
// 变更状态
state.value = newVal
}
},
actions: {
increment (context, newVal) {
context.commit('increment', newVal)
}
}
})
Action 函数接受一个与 store 实例具有相同方法和属性的 context 对象,因此你可以调用 context.commit
提交一个 mutation
三、项目结构
├── index.html
├── main.js
├── api
│ └── ... # 抽取出API请求
├── components
│ ├── App.vue
│ └── ...
└── store
├── index.js # 我们组装模块并导出 store 的地方
├── actions.js # 根级别的 action
├── mutations.js # 根级别的 mutation
四、具体使用
接上图结构
在 main.js 中引用
import store from './store' // 会自动寻找store文件夹下的index.js文件
...
new Vue({
store,
...
})
其中index.js 为组装模块并导出store的地方
import Vue from 'vue'
import Vuex from 'vuex'
import actions from './action'
import mutations from './mutations'
Vue.use(Vuex)
const state = {
name: '李白',
age: '100',
poem: '李白乘舟将欲行'
}
export default new Vuex.Store({
state,
actions,
mutations
})
actions.js 集中所有actions
export default {
changeUser(context, user) {
context.commit('changeUser', user);
}
...
}
mutations.js 集中所有mutations
export default {
changeUser(state, user) {
state.name = user;
}
...
}
使用方法:
1.使用 this.$store.dispatch() 触发 相应action
methods: {
addList () {
...
this.$store.dispatch('changeUser', this.title);
...
}
}
2.进入actions.js 中的 changeUser ,接着通过 context.commit() 提交一个 mutation changeUser
changeUser(context, user) {
context.commit('changeUser', user);
}
3.进入 mutations.js 中的 changeUser,通过 state.name = user 修改状态值。
changeUser(state, user) {
state.name = user;
}
至此,完成。
五、 补充函数
1. mapState
当一个组件需要获取多个状态的时候,将这些状态都声明为计算属性会有些重复和冗余。为了解决这个问题,我们可以使用 mapState
辅助函数帮助我们生成计算属性,让你少按几次键:
// 在单独构建的版本中辅助函数为 Vuex.mapState
import { mapState } from 'vuex'
export default {
// ...
computed: mapState({
// 箭头函数可使代码更简练
count: state => state.count,
// 传字符串参数 'count' 等同于 `state => state.count`
countAlias: 'count',
// 为了能够使用 `this` 获取局部状态,必须使用常规函数
countPlusLocalState (state) {
return state.count + this.localCount
}
})
}
当映射的计算属性的名称与 state 的子节点名称相同时,我们也可以给 mapState 传一个字符串数组。
computed: mapState([
// 映射 this.count 为 store.state.count
'count'
])
2. mapAction
使用 mapActions
辅助函数将组件的 methods 映射为 store.dispatch
调用(需要先在根节点注入 store
):
import { mapActions } from 'vuex'
export default {
// ...
methods: {
addList () {
...
// this.$store.dispatch('changeUser', this.title);
// 上边这句话可以用下边这句代替
thiS.increment('changeUser', this.title)
...
}
...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')`
})
}
}