概述

一般情况下,我们的vuex数据都是静态的,store在首次初始化后数据的格式就定好了,在日常使用中也确实应该这么做。

但是,随着业务的发展,vuex可能会变得非常的大,或者在多页面打包的时候,每个页面都需要vuex,但是如果把每个页面的vuex都写在一起,你会发现,原来我a页面可能只需要30个vuex的数据监听,但是会多出来其他页面的数据,这显然不应该的。

所以,我们需要一个能够动态加载模块的方法,每个页面动态加载自己的vuex数据使用。

api了解

vuex官方提供了几个api:

其中hasModule和unregisterModule就不一一介绍了,官网看个示例代码就好了。

使用

注册模块

import Vuex from 'vuex'

const store = new Vuex.Store({ /* 选项 */ })

// 注册模块 `myModule`
store.registerModule('myModule', {
  // ...
})
// 注册嵌套模块 `nested/myModule`
store.registerModule(['nested', 'myModule'], {
  // ...
})

举个我现实中项目的例子

有一个多页面打包的项目,里面的页面数量非常之多,如果所有的vuex都静态写好,那么一个页面会拥有所有页面的vuex数据,第一是加大的js的大小,第二是非常不好维护,打开modules目录,一堆文件,谁知道哪个文件是哪个页面的。

所以我的做法就是通过动态加载的方式引入自己页面的vuex,通过引入公共的vuex实例,利用实例的注册模块api进行注册就行了。

独立页面的目录结构:

├─ easyMoney
│  ├─ assets
│  ├─ components
│  ├─ router
│  ├─ store
│  ├─ ├─ modules
│  ├─ ├─ ├─ myModules.js
│  ├─ ├─ index.js
│  ├─ main.js

store中一个模块目录,里面存放着我当前easyMoney页面自己的vuex模块,index.js则是store的入口,他会导出注册完成模块后的store实例,交给main.js进行挂载。

代码展示:

myModules.js

export default {
  namespaced: true, //开启命名空间
  state: {
    name:"easyMoney",
  },
  getters:{
    name(state) {
      return state.name;
    }
  },
  mutations: {
    setName(state, name) {
      state.name = name;
    }
  },
  actions: {}
}

index.js

import store from "@/vuex/store";  //引入外部公用的vuex实例
//模块
import easyMoney from "./modules/easyMoney";


//动态注册
store.registerModule("easyMoney", easyMoney);

export default store;

为了安全其实可以增加一个hasModule的判断。

import store from "@/vuex/store";
//模块
import easyMoney from "./modules/easyMoney";


//动态注册
if (store.hasModule("easyMoney")) {
  throw new Error("easyMoney模块已存在,无法动态注册!");
}
store.registerModule("easyMoney", easyMoney);

export default store;

注意:hasModule是在vuex 3.2.0及以后添加的

最终我们在main.js中挂载就行了

main.js

import Vue from "vue";
import App from "./App.vue";
import store from "./store/index";

new Vue({
    el: "#app",
    store,
    render: h => h(App)
});
分类: vue 项目实战 标签: vuevuex动态注册vuex动态卸载vuex

评论

暂无评论数据

暂无评论数据

目录