返回顶部

vue——vuex的模块化module及命名空间namespaced

参考:https://vuex.vuejs.org/zh/guide/modules.html

     https://blog.csdn.net/weixin_43959963/article/details/111295725

     https://blog.csdn.net/weixin_43094619/article/details/120907918

 

我的问题在项目中使用vuex的module,控制台报错state为null,开启命名空间后,报错:[vuex]unknown action type 'xxx',[vuex] unknown getter ‘xxx’。

原因:开启命名空间后,模块的getter、action 及 mutation 使用时需要根据模块注册的路径调整。如:dispatch('cart/calculate', 5),cart就是模块名。

一. 前言

Vuex 为了便于维护store,允许将store分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割。

默认情况下,模块内部的 action 和 mutation 仍然是注册在全局命名空间的(即根节点store下)——这样使得多个模块能够对同一个 action 或 mutation 作出响应。

getter 同样也默认注册在全局命名空间,但是目前这并非出于功能上的目的(仅仅是维持现状来避免非兼容性变更)。必须注意,不要在不同的、无命名空间的模块中定义两个相同的 getter 从而导致错误。

若想要模块具有更高的封装度和复用性,可以通过添加 namespaced: true 的方式使其成为带命名空间的模块。当模块被注册后,它的所有 getter、action 及 mutation 都会自动根据模块注册的路径调整命名。

 

二. 实际使用

根节点 store.js:

import Vue from 'vue';
import Vuex from 'vuex';
import cart from './cart.js';

Vue.use(Vuex);

export default new Vuex.Store({
  modules: {
    cart,
  },
  state: {
    token: '',
  },
  getters: {
    token: (state) => {
      return state.token;
    },
  },
  mutations: {
    SET_TOKEN(state, data) {
      state.token = data.token;
    },
  },
});

 

1. 不使用命名空间

模块 cart.js:

const cart = {
  // 模块内容(module assets)
  state: () => ({
    count: 0, // 使用 -> state.count
    price: 0,
  }),
  getters: {
    // 这里的 `state` 对象是模块的局部状态
    count (state) {
      return state.count; // 使用 -> getters.count
    },
    price (state) {
      return state.price;
    }
  },
  mutations: {
    SET_COUNT(state) {
      // 这里的 `state` 对象是模块的局部状态
      state.count++;
    },
    SET_PRICE(state, total) {
      state.price = total;
    }, // 使用 -> commit('SET_PRICE', 20)
  },
  actions: {
    // rootState是根节点状态
    calculate({ state, commit, rootState }, data) {
      commit('SET_COUNT');
      commit('SET_PRICE', state.count * data);
    }, // 使用 -> dispatch('calculate', 5)
  }, 
}

export default cart;

辅助函数 mapGettersmapActions的使用:

...
import { mapGetters, mapActions } from 'vuex';
...
computed: {
  ...mapGetters(['token', 'count']),  
},
created() {
    this.calculate(5);
  },
methods: {
    ...mapActions(['calculate']),
},
...

 

2. 使用命名空间

模块 cart.js:

const cart = {
  namespaced: true, // 开启命名空间
  state: () => ({ //// 模块内的状态已经是嵌套的了,使用 `namespaced` 属性不会对其产生影响
    count: 0, // 使用 -> state.count
    price: 0,
  }),
  getters: {
    count (state) {
      return state.count; // 使用 -> getters['cart/count']
    },
    price (state) {
      return state.price;
    }
  },
  mutations: {
    SET_COUNT(state) {
      state.count++;
    },
    SET_PRICE(state, total) {
      state.price = total;
    }, // 使用 -> commit('cart/SET_PRICE', 20)
  },
  actions: {
    calculate({ state, commit, rootState }, data) {
      commit('SET_COUNT');
      commit('SET_PRICE', state.count * data);
    }, // 使用 -> dispatch('cart/calculate', 5)
  }, 
}

export default cart;

辅助函数 mapGettersmapActions的使用:

...
import { mapGetters, mapActions } from 'vuex';
...
computed: {
  ...mapGetters(['token'),
  ...mapGetters('cart', ['count']),  
},
created() {
    this.calculate(5);
  },
methods: {
    ...mapActions('cart', ['calculate']),
},
...

 

posted @ 2022-10-18 16:17  前端-xyq  阅读(569)  评论(0编辑  收藏  举报