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 阅读(93) 评论(0) 编辑 收藏 举报