最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 无星的前端之旅(十三)——require.context和vuex持久化

    正文概述 掘金(XingXiaoWu)   2021-01-13   460

    背景

    有些component需要全局注册的,但是在main.js中全局注册又太麻烦了。

    store采用modules方式分包,使用的时候也要手动注册。

    store刷新丢失,需要持久化。

    这时候解决前两个问题,可以使用require.context

    解决最后一个问题可以使用vuex-persistedstate

    require.context

    1.require.context是什么?

    Vue内置了webpack的部分配置,这个咱们就不多说了。

    require.context是webpack的api。

    2.require.context能干什么?

    通过执行require.context()函数可以获取一个特定的上下文,主要用来实现自动化导入模块。

    它允许您传递要搜索的目录,指示是否也应搜索子目录的标志以及用于匹配文件的正则表达式,然后自动导入,使得不需要每次显式的调用import导入模块。

    require.context()在构建时,webpack在代码中进行解析。

    全局自动注册component

    新建一个放置全局组件的文件夹,例如:components

    在components文件夹下新建一个js文件,例如:autoRegister.js

    vue2版本:

    // /components/autoRegister.js
    
    import Vue from 'vue';
    
    const componentsContext = require.context('./', true, /index.(vue|js)$/);
    componentsContext.keys().forEach((fileName) => {
      // 获取文件中的 default 模块
      const componentConfig = componentsContext(fileName).default;
      if (/.vue$/.test(fileName)) {
        console.log(componentConfig.name);
        Vue.component(componentConfig.name, componentConfig);
      } else {
        Vue.use(componentConfig);
      }
    });
    
    

    vue3版本:

    // /components/autoRegister.js
    
    const autoRegister = (app) => {
      const componentsContext = require.context('./', true, /index.(vue|js)$/);
      componentsContext.keys().forEach((fileName) => {
        // 获取文件中的 default 模块
        const componentConfig = componentsContext(fileName).default;
        if (/.vue$/.test(fileName)) {
          console.log(componentConfig.name);
          app.component(componentConfig.name, componentConfig);
        } else {
          app.use(componentConfig);
        }
      });
    };
    export default autoRegister;
    
    

    main.js中调用

    // vue2,是的,只需要引入就行了,因为js会默认执行
    import '@/components/autoRegister';
    
    // vue3
    import autoRegister from './components/autoRegister';
    autoRegister(app);
    

    自动分module注册store

    我们在store文件夹下新建一个index.js和一个modules文件夹

    vue2:

    // index.js
    import Vue from 'vue'
    import Vuex from 'vuex'
    
    Vue.use(Vuex)
    
    const modulesFiles = require.context('./modules', true, /\.js$/)
    
    const modules = modulesFiles.keys().reduce((modules, modulePath) => {
      const moduleName = modulePath.replace(/^\.\/(.*)\.\w+$/, '$1')
      const value = modulesFiles(modulePath)
      modules[moduleName] = value.default
      return modules
    }, {})
    
    const store = new Vuex.Store({
      modules,
    })
    
    export default store
    

    vue3:

    import { createStore } from 'vuex';
    
    const modulesFiles = require.context('./modules', true, /\.js$/)
    
    const modules = modulesFiles.keys().reduce((modules, modulePath) => {
      const moduleName = modulePath.replace(/^\.\/(.*)\.\w+$/, '$1')
      const value = modulesFiles(modulePath)
      modules[moduleName] = value.default
      return modules
    }, {})
    
    const store = createStore({
      modules,
      strict: process.env.NODE_ENV !== 'production',
    });
    export default store;
    
    

    关于分包的store,举个例子

    // /store/modules/exampleStore.js
    
    const state = {
    };
    
    const actions = {
      
    };
    
    const mutations = {
    
    };
    
    export default {
      namespaced: true,
      state,
      mutations,
      actions,
    };
    
    

    使用

    store.state.exampleStore.xxx
    

    vuex持久化

    持久化用vuex-persistedstate,这没有什么好说的了,用法看文档。

    这里要说的是配合require.context,如何让每个store里加上持久化

    在导出的时候我们可以看到,其实导出了一堆属性,最后都是通过

    modules[moduleName] = value.default

    的方式注入

    那我们是否可以多导出一个属性,通过一些方式,让指定属性用于本地持久化呢?

    答案是:可以

    我们对上面的东西稍作演化

    1.修改modules中的模块导出

    export default {              export default {  
      namespaced: true,             namespaced: true,
      state,                =>      state,
      mutations,                    mutations,
      actions,                      actions,
    };                              localStorage: ['name'],//假设state中需要持久化的key为name
                                  }
    

    2.在自动倒入中稍加判断是否存在localStorage

    vue2:

    import Vue from 'vue';
    import Vuex from 'vuex';
    import createPersistedState from 'vuex-persistedstate';
    
    Vue.use(Vuex);
    const modules = {};
    const modulePluginPaths = [];
    const requireModule = require.context('./modules', false, /.js$/);
    requireModule.keys().forEach((fileName) => {
      modules[fileName.slice(2, -3)] = requireModule(fileName).default;
      // 如果存在且大于0
      if (requireModule(fileName).default.localStorage?.length > 0) {
        requireModule(fileName).default.localStorage.forEach((item) => {
          modulePluginPaths.push(`${fileName.slice(2, -3)}.${item}`);
        });
      }
    });
    
    const store = new Vuex.Store({
      modules,
      strict: process.env.NODE_ENV !== 'production',
      plugins: [
        createPersistedState({
          paths: modulePluginPaths,
        }),
      ],
    });
    
    export default store;
    
    

    vue3:

    import { createStore } from 'vuex';
    import createPersistedState from 'vuex-persistedstate';
    
    const modules = {};
    const modulePluginPaths = [];
    const requireModule = require.context('./modules', false, /.js$/);
    requireModule.keys().forEach((fileName) => {
      modules[fileName.slice(2, -3)] = requireModule(fileName).default;
      // 如果存在且大于0
      if (requireModule(fileName).default.localStorage?.length > 0) {
        requireModule(fileName).default.localStorage.forEach((item) => {
          modulePluginPaths.push(`${fileName.slice(2, -3)}.${item}`);
        });
      }
    });
    
    const store = createStore({
      modules,
      strict: process.env.NODE_ENV !== 'production',
      plugins: [
        createPersistedState({
          paths: modulePluginPaths,
          // storage: window.sessionStorage,
        }),
      ],
    });
    
    export default store;
    
    

    这样无论怎么刷新,你需要持久化的内容,都被存到了localstorage中,使用起来方便无感

    以上内容,配合plop模板创建使用更加,请见

    无星的前端之旅(十四)——巧用plop生成模板进行偷懒


    起源地下载网 » 无星的前端之旅(十三)——require.context和vuex持久化

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元