咱們在作後臺系統的時候,常常會有比較多的功能頁面,每一個頁面或多或少都會有須要存儲在vuex中的數據,通常狀況下咱們會在state下定義不一樣的object,可是當功能一多,所有字段和action、mutations都定義在一個文件裏,不免會使文件變得很難維護。所有頁面的路由都定義在一個路由文件裏也會使文件代碼變得比較多,後期維護麻煩。因此咱們應該將倉庫和路由「模塊化」,不一樣功能定義不一樣的模塊文件,最後統一在index文件引入。javascript
router/index.js主要功能是:vue
// index.js import Vue from 'vue' import Router from 'vue-router' Vue.use(Router) // 定義常規路由 export const constantRoutes = [ { path: '/redirect', component: () => 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: () => import('@/views/404'), hidden: true } ] /** 權限路由 * 是動態的路由、須要根據權限加載的路由 */ const modulesFiles = require.context('./modules', true, /\.js$/) const routesModules = [] // 自動引入modules目錄下的全部模塊 modulesFiles.keys().reduce((modules, modulePath) => { const value = modulesFiles(modulePath) routesModules.push(value.default) }, {}) export const asyncRoutes = routesModules /** 404路由 * 最終沒法匹配到相應路由,重定向到404 * 異步加載路由時,在生成完異步路由準備掛載時,須要將重定向404的匹配規則定義在最後面,不然刷新會出錯。 */ export const notFoundRoutes = [ { path: '*', redirect: '/404', hidden: true, meta: { title: '404' } } ] // 定義實例化路由的方法 const createRouter = () => new Router({ // mode: 'history', // require service support scrollBehavior: () => ({ y: 0 }), routes: constantRoutes // 掛載常規路由 }) // 實例化路由 const router = createRouter() // 定義實重置路由的方法 export function resetRouter() { const newRouter = createRouter() router.matcher = newRouter.matcher // reset router } export default router 複製代碼
和router模塊同樣,咱也須要給store模塊建立一個文件夾,在裏頭存放定義文件java
該文件聲明瞭vuex實例,同時批量引入modules下的store文件,也聲明瞭vuex-persistedstate插件實例。git
關於persistedState的初始化,注意vuex中的參數不是所有都要持久化,你能夠根據業務邏輯自行定義須要持久化的參數 github
import Vue from 'vue' import Vuex from 'vuex' import getters from './getters' import createPersistedState from 'vuex-persistedstate' Vue.use(Vuex) // (建立了)一個包含了modules文件夾(包含子目錄)下面的,全部文件名以 `.js` 結尾的、能被 require 請求到的文件的上下文。 const modulesFiles = require.context('./modules', true, /\.js$/) // keys() 方法用於從modules建立一個包含modules裏鍵值的可迭代對象。 const modules = modulesFiles.keys().reduce((modules, modulePath) => { // 模塊名,取文件名 const moduleName = modulePath.replace(/^\.\/(.*)\.\w+$/, '$1') // 獲取鍵名爲modulePath的文件內容 const value = modulesFiles(modulePath) // 將文件中的默認導出模塊 賦值給迭代對象modules modules[moduleName] = value.default // 返回迭代對象modules return modules // 默認值是空對象{} }, {}) // 建立倉庫實例 const store = new Vuex.Store({ modules, getters, // 使用持久化插件 plugins: [ // 存儲vuex狀態,使之刷新不丟失 createPersistedState({ // 這裏我用的是localStorage,你也能夠改爲sessionStorage,cookie也行不過我沒研究嘻嘻嘻 storage: window.localStorage, reducer(val) { return { // 將要存儲的state中的值放在這裏 user: { name: val.user.name } } } }) ] }) export default store 複製代碼
那咱們就來看看咋使用,咱們能夠寫個userjs來試試,裏頭定義登陸登出的action,由於登陸登出可能不止一個地方會運用到,並且登陸登出可能會涉及到state裏頭好幾個狀態值的改變,因此我就把登陸登出的邏輯寫在action裏頭,這樣分發的時候也能夠改變狀態值:vue-router
import API from '@/assets/http/apiUrl' import Request from '@/assets/http' const user = { state: { token: '', name: '' }, mutations: { SET_TOKEN: (state, data) => { // 先初步定義token和username這兩個值 state.token = data localStorage.setItem('ADMIN_TOKEN', data) }, SET_NAME: (state, data) => { state.name = data } }, actions: { // 登錄 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) } }) }) }, // 短信登陸,這裏爲了方便我就直接複用登陸的action了,正式項目中確定要調用另外的接口 LoginByVin({ dispatch, commit }, params) { return dispatch('Login', params) }, // 重置token和state值 ResetToken({ commit }) { return new Promise(resolve => { commit('SET_TOKEN', '') commit('SEI_NAME', '') localStorage.removeItem('ADMIN_TOKEN') resolve() }) }, // 登出 LogOut({ dispatch, commit }) { return dispatch('ResetToken') } } } export default user 複製代碼
新建以後不須要在index那裏引入哦,由於咱們已經寫了批量引入的邏輯啦~是否是很方便呢vuex
而後就是使用了,關於Login,在登錄頁面只須要分發action就行:api
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 }) 複製代碼
具體代碼邏輯能夠下載項目來看一下下bash