vue-element-admin 项目代码学习 - 02 - vuex

411 阅读3分钟

vue-element-admin 项目代码学习 - 02 - vuex

前言

系列 vue-element-admin 项目代码学习,其他文章可参考:

vue-element-admin 项目代码学习 - 01 - main.js

话不多说,上代码

index.js

import Vue from 'vue'
import Vuex from 'vuex'
import getters from './getters'

Vue.use(Vuex)
// https://webpack.js.org/guides/dependency-management/#requirecontext
const modulesFiles = require.context('./modules', true, /\.js$/)

// you do not need `import app from './modules/app'`
// it will auto require all vuex module from modules file
const modules = modulesFiles.keys().reduce((modules, modulePath) => {
  // set './app.js' => 'app'
  const moduleName = modulePath.replace(/^\.\/(.*)\.\w+$/, '$1')
  const value = modulesFiles(modulePath)
  modules[moduleName] = value.default
  return modules
}, {})

const store = new Vuex.Store({
  modules,
  getters
})

export default store

项目中对vuex的数据使用模块化管理,在modules中按模块分别定义了,user(用户)、tagsView(标签)、settings(全局配置项)、permission(权限)、errorLog(错误日志)、app(全局状态模式),在对应的js文件中可以清晰的看到相应的字段和方法。

导入指定文件模块

const modulesFiles = require.context('./modules', true, /\.js$/)

webpack的api,通过执行require.context函数获取一个特定的上下文,主要用来实现自动化导入模块,在前端工程中,如果遇到从一个文件夹引入很多模块的情况,可以使用这个api,它会遍历文件夹中的指定文件,然后自动导入,使得不需要每次显式的调用import导入模块。

require.context函数接受三个参数

1.directory {String} -读取文件的路径

2.useSubdirectories {Boolean} -是否遍历文件的子目录

3.regExp {RegExp} -匹配文件的正则

require.context 返回一个函数,这个函数有三个属性

1.resolve {Function} -接受一个参数request,request为test文件夹下面匹配文件的相对路径,返回这个匹配文件相对于整个工程的相对路径

2.keys {Function} -返回匹配成功模块的名字组成的数组

3.id {String} -执行环境的id,返回的是一个字符串,主要用在module.hot.accept,应该是热加载?

这三个都是作为函数的属性(注意是作为函数的属性,函数也是对象,有对应的属性)

代码中通过keys方法,获取了名字组成的数组,通过正则替换,把文件名 xxx.js 换成 xxx, 然后使用reduce,遍历得到每个文件名为key,value为文件内容的 modules 对象,最后在vuex中引入。

modules/getter.js

对vuex中的state里的数据进行转换处理,就相当于 computed 计算属性一样。项目中可以看到他这里定义了之后再数据中取值不用再嵌套。

modules/user.js

用户token,name, roles 等都在该文件下处理,mutations中对定义的字段数据进行更变,在actions中异步定义 login 登录方法,拿到用户token,然后通过 getInfo 方法,传递token,拿到权限表,name等字段。 退出登录时调用 logout 方法。方法内部都使用promise处理异步。动态修改用户权限使用changeRoles 方法,重设token,权限表,动态路由等。
可以看到项目中的模块化做的很好,根据功能划分了不同的api接口,公共方法等,在自己的项目中值得借鉴。

modules/tagsView.js

tab标签上的数据在该文件下处理, 该页面定义了,visitedViewscachedViews 两个标签数组,一个是普通的,一个用作缓存时的。并依据业务对数据定义新增、编辑、删除等方法。

modules/settings.js

全局配置项设置文件,该页面定义了,是否显示右侧页面设置按钮、tagsview、侧边栏徽标等。

modules/permission.js

路由表数据定义,页面中定义了用户路由表字段,定义了generateRoutes 方法通过传入权限,从router文件里定义的动态路由过滤出有当前权限的路由表。然后mutations修改数据。

  generateRoutes({ commit }, roles) {
    return new Promise(resolve => {
      let accessedRoutes
      if (roles.includes('admin')) {
        accessedRoutes = asyncRoutes || []
      } else {
        accessedRoutes = filterAsyncRoutes(asyncRoutes, roles)
      }
      commit('SET_ROUTES', accessedRoutes)
      resolve(accessedRoutes)
    })
  }

modules/errorLog.js: 错误日志数据搜集

modules/app.js: 侧边栏状态,页面整体文字大小设置。配合cookie一起使用。

个人学习,可能理解有不足的地方,谢谢~