background

Some components require global registration, but it’s too cumbersome to do so in main.js.

The store is subcontracted in modules, and you need to register manually when using it.

The store refresh is lost and needs to be persisted.

To solve the first two problems, you can use require.context

For the last problem, use vuex-PersistedState

require.context

1. What is require.context?

Vue has some built-in webPack configurations, which we won’t go into.

Require. context is the WEBPack API.

2. What can require. Context do?

A specific context is obtained by executing the require.context() function, which is used to automate the import of modules.

It allows you to pass in the directory to search, a flag indicating whether subdirectories should also be searched, and a regular expression to match the file, and then import automatically so that you don’t need to explicitly call import each time to import the module.

Require.context () is parsed in the code by WebPack at build time.

Component is automatically registered globally

Create a new folder for global components, such as components

Create a new js file in the Components folder, for example, autoregistrie.js

Vue2 version:

// /components/autoRegister.js

import Vue from 'vue';

const componentsContext = require.context('/'.true./index.(vue|js)$/);
componentsContext.keys().forEach((fileName) = > {
  // Get the default module in the file
  const componentConfig = componentsContext(fileName).default;
  if (/.vue$/.test(fileName)) {
    console.log(componentConfig.name);
    Vue.component(componentConfig.name, componentConfig);
  } else{ Vue.use(componentConfig); }});Copy the code

Vue3 version:

// /components/autoRegister.js

const autoRegister = (app) = > {
  const componentsContext = require.context('/'.true./index.(vue|js)$/);
  componentsContext.keys().forEach((fileName) = > {
    // Get the default module in the file
    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;

Copy the code

In the main. Js calls

// vue2, yes, it only needs to be introduced, because js will execute by default
import '@/components/autoRegister';

// vue3
import autoRegister from './components/autoRegister';
autoRegister(app);
Copy the code

Automatically register the Store by module

Let’s create a new index.js and a Modules folder in the Store folder

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
Copy the code

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;

Copy the code

For a subcontracted store, let’s take an example

// /store/modules/exampleStore.js

const state = {
};

const actions = {
  
};

const mutations = {

};

export default {
  namespaced: true,
  state,
  mutations,
  actions,
};

Copy the code

use

store.state.exampleStore.xxx
Copy the code

Vuex persistence

Persist with vuex-PersistedState, there is nothing to say about this, see the documentation for usage.

What I’m talking about here is with require.context, how do I get persistence in every store

When we export, we can see that we’re actually exporting a bunch of properties, all of which are passed

modules[moduleName] = value.default

Injection mode

Can we export one more property, in some way, so that the specified property is used for local persistence?

The answer is: yes

Let’s take a little bit of evolution of what’s up there

1. Modify the module export in Modules

export default { export default { namespaced: true, namespaced: true, state, => state, mutations, mutations, actions, actions, }; LocalStorage: ['name'],// suppose the state key is name}Copy the code

2. Check whether localStorage exists in the automatic pouring

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;
  // If it exists and is greater than 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;

Copy the code

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;
  // If it exists and is greater than 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;

Copy the code

So no matter how refreshing, you need to persist the content, are stored in the localstorage, easy to use without feeling

For details about how to create and use the ploP template, see

Starless Front End Journey (xiv) – Lazy with ploP generation templates