When we are working on the background system, there are often many functional pages, and each page will have more or less data that needs to be stored in VUEX. In general, we will define different objects under state, but when there are many functions, all fields, action and mutations will be defined in one file. It will inevitably make the file difficult to maintain. All the routes of the page are defined in a routing file will also make the file code become more, later maintenance trouble. Therefore, we should “modularize” warehouse and routing, define different module files for different functions, and finally unify the introduction in index file.
1. Routing module
1.1 Creating a Router folder to store route definition files
- Create modules folder, mainly to store the function page route definition file
- Create the index.js file to define the route
1.1 1 @ / router/index. Js
Router /index.js provides the following functions:
- Define general routes, i.e. pages that do not require permissions to access, such as login registration, background home page, 404 page, etc.
- Import routing modules that need to be loaded based on permissions
- Define methods for creating and resetting routes
// index.js
import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)
// Define a regular route
export const constantRoutes = [
{
path: '/redirect'.component: (a)= > import('@/layout'),
hidden: true.children: [{path: '/redirect/:path*'.component: resolve= > void require(['@/views/redirect/index'], resolve)
}
]
},
{
path: '/'.redirect: '/login'
},
{
path: '/login'.name: 'Login'.component: resolve= > void require(['@/views/login/index'], resolve),
hidden: true
},
{
path: '/register'.name: 'Register'.component: resolve= > void require(['@/views/login/register'], resolve),
hidden: true
},
{
path: '/resetPsw'.name: 'ResetPsw'.component: resolve= > void require(['@/views/login/resetPsw'], resolve),
hidden: true
},
{
path: '/ 404'.component: (a)= > import('@/views/404'),
hidden: true}]/** Permission route * is a dynamic route that needs to be loaded according to permission */
const modulesFiles = require.context('./modules'.true, /\.js$/)
const routesModules = []
// Automatically imports all modules in the modules directory
modulesFiles.keys().reduce((modules, modulePath) = > {
const value = modulesFiles(modulePath)
routesModules.push(value.default)
}, {})
export const asyncRoutes = routesModules
/** 404 route * Failed to match the corresponding route and was redirected to 404 * When the asynchronous route is loaded, the matching rule of 404 must be defined at the end of the asynchronous route generation and ready to mount. Otherwise, the refresh will fail. * /
export const notFoundRoutes = [
{
path: The '*'.redirect: '/ 404'.hidden: true.meta: {
title: '404'}}]// Define a method to instantiate the route
const createRouter = (a)= > new Router({
// mode: 'history', // require service support
scrollBehavior: (a)= > ({ y: 0 }),
routes: constantRoutes // Mount the regular route
})
// Instantiate the route
const router = createRouter()
// Define a real route reset method
export function resetRouter() {
const newRouter = createRouter()
router.matcher = newRouter.matcher // reset router
}
export default router
Copy the code
Vuex warehouse module
As with the Router module, we also need to create a folder for the Store module to store the definition files
2.1 Create a Store folder to store vuex definition files
- Create modules folder, mainly store the warehouse definition file under each module
- Create the index.js file and initialize the vuex instance
- Use Vuex Persistence, persistedState, to refresh your data without losing it
2.1 1 @ / store/index. Js
This file declares the vuex instance. It also introduces the store file under Modules in bulk. It also declares the vuex-PersistedState instance.
In terms of persistedState initialization, note that not all parameters in VUex need to be persisted. You can define the parameters that need to be persisted according to the business logic
import Vue from 'vue'
import Vuex from 'vuex'
import getters from './getters'
import createPersistedState from 'vuex-persistedstate'
Vue.use(Vuex)
// a context that contains all files under the Modules folder with names ending in '.js' that can be requested by require.
const modulesFiles = require.context('./modules'.true, /\.js$/)
The // keys() method is used to create an iterable from modules containing the keys in modules.
const modules = modulesFiles.keys().reduce((modules, modulePath) = > {
// Module name, take the filename
const moduleName = modulePath.replace(/^\.\/(.*)\.\w+$/.'$1')
// Get the contents of the file with the key name modulePath
const value = modulesFiles(modulePath)
// Assign the default export module in the file to the iterator modules
modules[moduleName] = value.default
// Return the iterator modules
return modules
// Default is empty object {}
}, {})
// Create a repository instance
const store = new Vuex.Store({
modules,
getters,
// Use persistent plug-ins
plugins: [
// Store vuEX state so that it is not lost when refreshed
createPersistedState({
// sessionStorage = sessionStorage = sessionStorage = sessionStorage = sessionStorage = sessionStorage = sessionStorage = sessionStorage = sessionStorage = sessionStorage = sessionStorage = sessionStorage = sessionStorage = sessionStorage = sessionStorage = sessionStorage
storage: window.localStorage,
reducer(val) {
return {
// Place the value of the state to be stored here
user: {
name: val.user.name
}
}
}
})
]
})
export default store
Copy the code
So let’s see how it works, we can try it out by writing a userJS that defines login and logout actions, because login and logout can be used in more than one place, and login and logout can involve several changes in state values, so I’m going to put the login and logout logic in the action, It is also possible to change the status value when distributing:
Create user.js in the 2.1-2 modules directory to store user information and define login and logout actions
import API from '@/assets/http/apiUrl'
import Request from '@/assets/http'
const user = {
state: {
token: ' '.name: ' '
},
mutations: {
SET_TOKEN: (state, data) = > {
// Define the token and username values
state.token = data
localStorage.setItem('ADMIN_TOKEN', data)
},
SET_NAME: (state, data) = > {
state.name = data
}
},
actions: {
/ / login
Login({ commit }, params) {
return new Promise((resolve, reject) = > {
Request.httpRequest({
method: 'post'.url: API.Login,
params: params,
success: data= > {
commit('SET_TOKEN', data.token)
resolve(data)
},
error: err= > {
reject(err)
}
})
})
},
// SMS login, for the sake of convenience I directly reuse the login action, the formal project must call another interface
LoginByVin({ dispatch, commit }, params) {
return dispatch('Login', params)
},
// Reset the token and state values
ResetToken({ commit }) {
return new Promise(resolve= > {
commit('SET_TOKEN'.' ')
commit('SEI_NAME'.' ')
localStorage.removeItem('ADMIN_TOKEN')
resolve()
})
},
/ / logout
LogOut({ dispatch, commit }) {
return dispatch('ResetToken')}}}export default user
Copy the code
We don’t need to import it in index, because we already wrote the batch import logic
For Login, just distribute the action on the Login page:
params = {
'username': this.loginForm.user,
'password': this.loginForm.password
}
this.$store.dispatch('Login', params).then(() => {
this.loading = false
this.$router.push({ path: this.redirect || '/home' })
}).catch(() => {
this.loading = false
})
Copy the code
The specific code logic can be downloaded to see the project
- A responsive background management system based on Vuecli3 and vuE-admin-Template transformation