VUE - Vuex/store
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。为了解决以上问题,Vuex允许我们将store分割成模块(module)。每个模块拥有自己的state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割:

一、使用了命名空间
如果希望你的模块具有更高的封装度和复用性,你可以通过添加 namespaced: true 的方式使其成为带命名空间的模块。当模块被注册后,它的所有 getter、action 及 mutation 都会自动根据模块注册的路径调整命名。
import Vue from 'vue'
import Vuex from 'vuex'
import app from './modules/app'
import user from './modules/user'
import getters from './getters'
Vue.use(Vuex)
const store = new Vuex.Store({
modules: {
app,
user
},
getters
})
export default store
其中 getters:
const getters = {
sidebar: state => state.app.sidebar,
size: state => state.app.size,
device: state => state.app.device
token: state => state.user.token,
avatar: state => state.user.avatar,
name: state => state.user.name,
introduction: state => state.user.introduction,
roles: state => state.user.roles,
permissions: state => state.user.permissions
}
export default getters
我们通过提交 mutation 的方式,而非直接改变 store.state.count,是因为我们想要更明确地追踪到状态的变化。app module 示例:
import Cookies from 'js-cookie'
const state = {
sidebar: {
opened: Cookies.get('sidebarStatus') ? !!+Cookies.get('sidebarStatus') : true,
withoutAnimation: false
},
device: 'desktop',
size: Cookies.get('size') || 'medium'
}
const mutations = {
TOGGLE_SIDEBAR: state => {
state.sidebar.opened = !state.sidebar.opened
state.sidebar.withoutAnimation = false
if (state.sidebar.opened) {
Cookies.set('sidebarStatus', 1)
} else {
Cookies.set('sidebarStatus', 0)
}
},
CLOSE_SIDEBAR: (state, withoutAnimation) => {
Cookies.set('sidebarStatus', 0)
state.sidebar.opened = false
state.sidebar.withoutAnimation = withoutAnimation
},
TOGGLE_DEVICE: (state, device) => {
state.device = device
},
SET_SIZE: (state, size) => {
state.size = size
Cookies.set('size', size)
}
}
const actions = {
toggleSideBar({ commit }) {
commit('TOGGLE_SIDEBAR')
},
closeSideBar({ commit }, { withoutAnimation }) {
commit('CLOSE_SIDEBAR', withoutAnimation)
},
toggleDevice({ commit }, device) {
commit('TOGGLE_DEVICE', device)
},
setSize({ commit }, size) {
commit('SET_SIZE', size)
}
}
export default {
namespaced: true,
state,
mutations,
actions
}
一般使用action来提交更改
this.$store.dispatch('app/setSize', size)
取vuex state的时候可以直接使用:
this.$store.state.permission.topbarRouters;
如果有getters的话,也可以通过getters来取:
this.$store.getters.permission_routes
使用vuex 提供的辅助函数 来取:
mapGetters 辅助函数是将 store 中的 getter 映射到局部计算属性:
当映射的计算属性的名称与 state 的子节点名称相同时,我们也可以给 mapState 传一个字符串数组;
computed: {
...mapState(["settings"]),
...mapGetters(["sidebarRouters", "sidebar"])
}
如果你想将一个 getter 属性另取一个名字,使用对象形式:
...mapGetters({
// 把 `this.doneCount` 映射为 `this.$store.getters.doneTodosCount`
doneCount: 'doneTodosCount'
})
vue-devtool :

二、未使用命名空间
如果modules未使用命名空间 ,默认情况下,模块内部的 action、mutation 和 getter 是注册在全局命名空间的——这样使得多个模块能够对同一 mutation 或 action 作出响应。则有如下规则:
组件中获取state值的时候,通过指定模块名来获取,$store.state.a.name
组件中调用 模块的 mutations 时,和普通的调用方法一样,直接commit 名字即可,如果模块间有重名的,则都会执行,一般情况下 我们避免模块有重名的mutation;
组件中调用 模块的 getters 时,和普通的调用方法一样,直接getters 名字即可,如果模块间有重名的,则会报错,但会之心后面的getter,一般情况下,我们避免模块getters重名。
组件中调用 模块的 action 时,和普通的调用方法一样,直接dispatch名称即可,如果模块间有重名的,则都会执行,一般情况下,我们避免模块间action重名。
三、混用
可以在一个store中同时使用命名空间、非命名空间,调用时 根据各自的规则进行调用即可。
参考:https://vuex.vuejs.org/zh/guide/modules.html#%E6%A8%A1%E5%9D%97%E7%9A%84%E5%B1%80%E9%83%A8%E7%8A%B6%E6%80%81
posted on 2021-12-30 11:02 TrustNature 阅读(113) 评论(0) 收藏 举报
浙公网安备 33010602011771号