vuex@3

146 阅读1分钟

定义vuex (this指向Store实例,可以通过 this._vm 访问Vue实例)

import Vue from 'vue'
import Vuex from 'vuex'
import createPersistedState from 'vuex-persistedstate';
import user from './modules/user'
import dataManagerService from './modules/dataManagerService'
Vue.use(Vuex)

const store = new Vuex.Store({
  /**
   * @desc 持久化插件(vuex-persistedstate) (修改state后触发才可以看到本地存储数据的的变化)
   * @param {storage}  默认是存储在 localStorage 中 
   * @param {paths}  是存储 module 中的指定state的键, 若是module,则存储整个 module 中的所有state; 若是某个state的key,则只存储该项
   */
  plugins: [createPersistedState({
    /**
     * 以下分别是localStorage存储 user 整个module; dataManagerService这个module中的activeBillMacButton; token(注意持久化存储不能存储Map等数据结构的值)
     */
    paths: ["user", "dataManagerService.activeBillMacButton", "token"]
  })],
  // modules 中
  modules: {
    user,
    theme,
    dataManagerService
  },
  state: {
    token: "", //登录成功的token
    dictMap: new Map() //字典map
  },
  mutations: {
    setToken (state, token) {
      state.token = token
    },
    setDictMap (state, dictMap) {
      state.dictMap = dictMap
    }
  },
  actions: {
    /**
     * @desc 登录成功并初始化字典类信息
     * @param {payloads} 登录接口所需的参数
     */
    async loginAndInitAsync ({ commit, state }, payloads) {
      const loginRes = await this._vm.$SendRequest(payloads);
      const token = loginRes?.access_token;
      commit('setToken', token)
      const dictsRes = await this._vm.$SendRequest({
        url: "/cloud/sys/common/dict/map",
      });
      const dictMap = new Map();
      Object.entries(dictsRes).forEach(([type, dicts]) => {
        let dictList = [];
        for (const key in dicts) {
          dictList.push({ name: dicts[key], value: key })
        }
        dictMap.set(type, dictList)
      })
      commit('setDictMap', dictMap)
      console.log('dictMap', dictMap);
    }
  },
  getters: {
    // this.$store.getters.getDictsByType(type,true)
    getDictsByType: (state, getters) => (type, needOptionOfAll = false) => {
      const dictMap = state.dictMap.get(type);
      if (needOptionOfAll) {
        dictMap.unshift({ name: "全部", value: null })
      }
      return state.dictMap.get(type)
    }
  }
})

组件中使用vuex(获取根目录下的不带模块路径即可),以下演示了通过辅助函数和直接操作两大类

//

import { mapState, mapGetters, mapMutations, mapActions} from 'vuex'


computed: {
     // 获取根路径下的
     ...mapState(['token']),
    
    
    ...mapState({
      a: state => state.some.nested.module.a, // this.a
      b: state => state.some.nested.module.b // this.b
    }),
    ...mapState('some/nested/module', [
      'stateName' // -> this.stateName
    ]),
    ...mapGetters('moduleName', [
      'getterName', // -> this.getterName
    ]),
  },
  methods: {
    methods: {
      ...mapActions([
        'moduleName/actionName', // -> this['moduleName/actionName']()
      ]),
      ...mapActions('moduleName', [
        'actionName', // -> this.actionName()
      ]),
      ...mapMutations('moduleName', [
        'mutationName', // -> this.mutationName()
      ]),
      test () {
        // 获取根路径下的
        const token = this.$store.state.token;
        this.$store.commit('setToken', "123456")
        
        
        // 获取 state
        this.$store.state['moduleName/stateName']
        // 获取 getters
        this.$store.getters['moduleName/getterName']
        // 触发 actions
        this.$store.dispatch('moduleName/actionName')
        // 触发 mutations
        this.$store.commit('moduleName/mutationName')
      }
    }
  },

modules

const moduleA = {
  namespaced: true,
  state:{},
  mutations: { ... },
  actions: { ... },
  getters: { ... }
}

注意点 需遵守 Vue 的响应规则

  1. 最好提前在你的 store 中初始化好所有所需属性。
  2. 当需要在对象上添加新属性时,你应该
  • 使用 Vue.set(obj, 'newProp', 123),
  • 以新对象替换老对象。