这是我参与更文挑战的第4天,活动详情查看: 更文挑战
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化
本章讲解 Vue 项目中 Vuex 的具体使用
先在项目目录下建立一个 store 文件夹,并且在下面建立一个 index.js 文件
// index.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
复制代码
在 Vue 实例上挂载 store
// main.js
import store from '@/store'
new Vue({
el: '#app',
store
})
复制代码
在全局去使用store,在组件里就可以通过 this.$store.state.data 全局调用
创建 modules
当应用比较非常复杂时,Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割
例:modules / user 模块
每个状态集最后合成到index.js中
模块中的 state、getters、mutations、actions
state
const state = {
pool_list_data: '',
pool_id_list: [],
current_pools: {
poolId: "CIDC-RP-25",
poolName: "华东-苏州",
},
}
this.$store.state.user.pool_list_data
复制代码
通过 store.state
来获取状态对象,以及通过 store.commit 方法触发状态变更
Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新
不能直接改变 store 中的状态。改变 store 中的状态的唯一途径就是显式地提交 (commit) mutation。这样使得我们可以方便地跟踪每一个状态的变化,从而让我们能够实现一些工具帮助我们更好地了解我们的应用
由于 store 中的状态是响应式的,在组件中调用 store 中的状态简单到仅需要在计算属性中返回即可。触发变化也仅仅是在组件的 methods 中提交 mutation
getters
const getters = {
doneTodos: state => {
return state.todos.filter(todo => todo.done)
}
pool_list_data: state => state.pool_list_data,
pool_id_list: state => state.pool_id_list,
current_pools: state => state.current_pools,
}
store.getters["user/doneTodos"]
复制代码
getter可以认为是 store 的计算属性,就像计算属性一样,getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算
也可以通过让 getter 返回一个函数,来实现给 getter 传参。在你对 store 里的数组进行查询时非常有用
注意:getter 在通过方法访问时,每次都会去进行调用,而不会缓存结果
mapGetters
mport { mapGetters } from 'vuex'
export default {
// ...
computed: {
// 使用对象展开运算符将 getter 混入 computed 对象中
...mapGetters([
'doneTodosCount',
'anotherGetter',
// 使用对象形式,可以给 getter 属性另取一个名字
// doneCount: 'doneTodosCount'
])
}
}
复制代码
mapGetters 辅助函数仅仅是将 store 中的 getter 映射到局部计算属性
mutations
更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。Vuex 中的 mutation 非常类似于事件:每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数
你可以向 store.commit 传入额外的参数,即 mutation 的 载荷(payload)
const mutations = {
'SET_POOL_INFO'(state, pooldata) {
state.pool_list_data = pooldata
state.pool_id_list = []
pooldata.forEach((i) => {
state.pool_id_list.push(i.poolId)
})
},
'SET_CURRENT_POOLS'(state, region_data) {
state.current_pools.poolId = region_data.value
state.current_pools.poolName = region_data.name
}
}
commit('SET_CURRENT_POOLS', region_data)
复制代码
actions
Action 类似于 mutation,不同在于:
- Action 提交的是 mutation,而不是直接变更状态
- Action 可以包含任意异步操作
const actions = {
async getInfo({ commit }) {
return new Promise(async (resolve, reject) => {
commit('SET_ROLES', ['Admin'])
axios.defaults.headers.common["pool-Id"] = state.current_pools.poolId
const user = await getUserInfo({ user_id: state.user_id })
if (user.status == 200) {
commit('SET_ECLOUD_USER', user.data)
}
resolve(state.roles)
})
},
}
// Action 通过 store.dispatch 方法触发,同样支持载荷方式和对象方式进行分发
this.$store.dispatch('user/getInfo')
复制代码
mapActions
在组件中使用 this.$store.dispatch(‘xxx’) 分发 action,或者使用 mapActions 辅助函数将组件的 methods 映射为 store.dispatch 调用
mport { mapActions } from 'vuex'
export default {
// ...
methods: {
...mapActions([
'user/getInfo',
// 将 this.increment() 映射为 this.$store.dispatch('user/getInfo')
// mapActions 也支持载荷,及对象形式
]),
}
}
复制代码