目录
其中 common 文件夹是通用的不需要按需引入的,modules 文件夹需要按需引入 modules文件夹下 ts文件的名称要与对应的vue组件name属性的值一致;
例如:home.vue的name为:home,那其相对应的modules文件夹下的 ts 为: home.ts
store/index.ts
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
// 使用 require.context 动态引入 vuex modules
const modulesFiles = require.context('./common', true, /\.ts$/)
const modules = modulesFiles.keys().reduce((module: any, modulePath) => {
const moduleName = modulePath.replace(/^\.\/(.*)\.\w+$/, '$1')
const value = modulesFiles(modulePath)
module[moduleName] = value.default
return module
}, {})
export default new Vuex.Store({
state: {},
mutations: {},
actions: {},
modules
})
main.ts
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import demandVuexModules from '@/utils/dynamic/demandVuexModules'
Vue.config.productionTip = false
// 执行 按需引入当方法
demandVuexModules(Vue, router, store)
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
src/utils/dynamic/demandVuexModules.ts
let allowsArr = ['home'] // 需要按需加载页面的vue组件name属性的值
export default (Vue: any, router: any, store: any) => {
// 注册 按需引入的vuex modules
Vue.use(function () {
Vue.mixin({
beforeCreate: function () {
// $options是组件选项,包含组件.vue文件的 `export default` 的属性
// 为了拿到在组件定义的是否按需加载的属性值 `isNeedVuex`
let name: any = this.$options['name']
if (name && allowsArr.includes(name)) {
// 需要设置.vue文件的name属性,跟单文件组件名字命名一样
import('@/store/modules/' + name).then(res => {
// res.default就是代表我们在store/modules文件夹下对应文件的export default对象
// registerModule是vuex自带的方法,请自行搜索
// 第一个参数是动态注入的模块名,第二个参数是模块导出对象
this.$store.registerModule(name, res.default)
})
}
}
})
})
// 注销 按需引入的vuex modules
router.beforeEach((to: any, from: any, next: any) => {
if (from.name && allowsArr.includes(from.name)) {
// unregisterModule跟前面的registerModule对应,是vuex的api,请自行搜索
store.unregisterModule(from.name)
}
// <!--to do others-->
next()
})
}
问题
这样使用会报错
原因:
按需引入的vuex modules是异步的 在这里访问的时候还没有加载成功
解决办法
这样引入就可以了