Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
以下是一个表示“单向数据流”理念的简单示意:
但是,当我们的应用遇到多个组件共享状态时,单向数据流的简洁性很容易被破坏:
- 多个视图依赖于同一状态。
- 来自不同视图的行为需要变更同一状态。
对于问题一,传参的方法对于多层嵌套的组件将会非常繁琐,并且对于兄弟组件间的状态传递无能为力。
对于问题二,我们经常会采用父子组件直接引用或者通过事件来变更和同步状态的多份拷贝。以上的这些模式非常脆弱,通常会导致无法维护的代码。
因此,我们为什么不把组件的共享状态抽取出来,以一个全局单例模式管理呢?在这种模式下,我们的组件树构成了一个巨大的“视图”,不管在树的哪个位置,任何组件都能获取状态或者触发行为!
在根实例中注册 store 选项
在 main.js 文件中引入:
import store from './store'
new Vue({
store,
router,
render: h => h(App)
}).$mount('#app')
state
state 中保存着所有的全局变量,写法:
state: {
lines: [],
platforms: [],
bugTypes: [],
bugLevels: [],
bugSources: [],
notifyPeoples: []
}
mapState函数
这些变量要在组件中获取使用 computed 计算属性
computed: {
...mapState({
lineRes: state => state.manageModule.lines,
platformRes: state => state.manageModule.platforms,
bugTypeRes: state => state.manageModule.bugTypes,
levelRes: state => state.manageModule.bugLevels,
sourceRes: state => state.manageModule.bugSources,
peopleRes: state => state.manageModule.notifyPeoples
})
}
mutation
mutation定义了一系列更改 Vuex 的 store 中的状态的方法,提交(commit)mutation中的方法,就可以按照方法中定义的操作来改变 store 中的值。
一条重要的原则就是要记住 mutation 必须是同步函数
setLines: (state, payload) => {
state.lines = payload
},
setPlatforms: (state, payload) => {
state.platforms = payload
}
Action
Action 提交的是 mutation, 而不是直接变更状态。
Action 可以包含任何异步操作
getDatas: ({ commit }, searchType) => {
switch (searchType) {
case 'line':
return manageService.getLines().then(res => {
commit('setLines', res)
})
default:
break
}
}
mapActions
将 mapActions 里的函数都声明在一个数组里,这样在使用这些函数的时候就直接使用 this.getDatas(this.mySelect) 就可以了。
methods: {
...mapActions([
'getDatas'
]),
handleClick (tab) {
this.$router.push({
path: '/dictionary',
query: {
tabName: String(tab.name)
}
})
this.getDatas(this.mySelect)
}
}