对vue-element-admin后台开源框架的解读---vuex篇

对vue-element-admin后台开源框架的解读—vuex篇

在这里插入图片描述

文件夹示意

Store文件夹
index.js 文件
modules各模块文件夹
页面模块app.js
设置模块setting.js
用户模块user.js
路由权限模块permission.js
各个功能模块.....xxx.js
getters.js 文件

在这里插入图片描述

1.vuex核心–index.js

项目代码

import Vue from 'vue'
import Vuex from 'vuex'
import getters from './getters'
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,
  getters
})

export default store

解析1
批量引入vuex module从modules文件夹(对于模块特别多的vuex非常方便)不需要一个一个去import.

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

Webpack API ----- require.context() 函数来创建自己的 context。
可以给这个函数传入三个参数:

  1. 一个要搜索的目录
  2. 一个标记表示是否还搜索其子目录
  3. 一个匹配文件的正则表达式。

示例

require.context('../', true, /\.stories\.js$/);
// (创建出)一个 context,其中所有文件都来自父文件夹及其所有子级文件夹,request 以 `.stories.js` 结尾。

require.context 知识点来源
解析2
对批量引入的模块通过数组的reduce方法让所有摸块组成一个大对象
把每一个js模块文件格式化为模块名 ./app.js’ => ‘app’
通过modulesFiles(modulePath)获取每个模块的内容

const modules = modulesFiles.keys().reduce((modules, modulePath) => {
const moduleName = modulePath.replace(/^./(.*).\w+$/, ‘$1’)
const value = modulesFiles(modulePath)
modules[moduleName] = value.default
return modules
}, {})

js中的reduce()函数讲解
解析3
将vuex模块和getters注入store,并导出

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

2.vuex的计算属性–getters.js

将getters单独创建一个模块,配合 mapGetters 辅助函数可以很方便的获取vuex中的一些简单数据

const getters = {
  sidebar: state => state.app.sidebar,
  device: state => state.app.device,
  token: state => state.user.token,
  ......
}
export default getters

mapGetters 辅助函数获取数据
在组件中直接获取token

computed: {
    ...mapGetters(['token'])
 }

3.vuex模块—登录,获取用户信息,登出模块–user.js

import { login, logout, getInfo } from '@/api/user'
import { getToken, setToken, removeToken } from '@/utils/auth'
import router, { resetRouter } from '@/router'

const state = {
  token: getToken(),
  name: '',
  avatar: '',
  introduction: '',
  roles: []
}
// 注册所有的mutation方法
const mutations = {
//将函数赋值给一个变量
  SET_TOKEN: (state, token) => {
    state.token = token
  },
  SET_INTRODUCTION: (state, introduction) => {
    state.introduction = introduction
  },
  SET_NAME: (state, name) => {
    state.name = name
  },
  SET_AVATAR: (state, avatar) => {
    state.avatar = avatar
  },
  SET_ROLES: (state, roles) => {
    state.roles = roles
  }
}
//注册所有的action方法
const actions = {
  // 登录
  // 将commit 从 context 中结构出来
  // Promise封装的组合式action
  login({ commit }, userInfo) {
    const { username, password } = userInfo
    return new Promise((resolve, reject) => {
      login({ username: username.trim(), password: password }).then(response => {
        const { data } = response
        commit('SET_TOKEN', data.token)
        setToken(data.token)
        resolve()
      }).catch(error => {
        reject(error)
      })
    })
  },

  // 获取用户信息
  // 将commit,state从 context 中结构出来
  getInfo({ commit, state }) {
    return new Promise((resolve, reject) => {
      getInfo(state.token).then(response => {
        const { data } = response

        if (!data) {
          reject('Verification failed, please Login again.')
        }

        const { roles, name, avatar, introduction } = data

        // roles must be a non-empty array
        if (!roles || roles.length <= 0) {
          reject('getInfo: roles must be a non-null array!')
        }

        commit('SET_ROLES', roles)
        commit('SET_NAME', name)
        commit('SET_AVATAR', avatar)
        commit('SET_INTRODUCTION', introduction)
        resolve(data)
      }).catch(error => {
        reject(error)
      })
    })
  },

  // 登出
  // 将commit, state, dispatch 从 context 中结构出来
  logout({ commit, state, dispatch }) {
    return new Promise((resolve, reject) => {
      logout(state.token).then(() => {
        commit('SET_TOKEN', '')
        commit('SET_ROLES', [])
        removeToken()
        resetRouter()

        // reset visited views and cached views
        // to fixed https://github.com/PanJiaChen/vue-element-admin/issues/2485
        dispatch('tagsView/delAllViews', null, { root: true })

        resolve()
      }).catch(error => {
        reject(error)
      })
    })
  },

 // 清除token
  resetToken({ commit }) {
    return new Promise(resolve => {
      commit('SET_TOKEN', '')
      commit('SET_ROLES', [])
      removeToken()
      resolve()
    })
  },

  // 动态地修改权限
  // async,await封装的组合式action
  async changeRoles({ commit, dispatch }, role) {
    const token = role + '-token'

    commit('SET_TOKEN', token)
    setToken(token)

    const { roles } = await dispatch('getInfo')
    resetRouter()
    // 生成基于角色的可访问路由
    // 需要分发其他模板的action或者提交其他模板的mutation的时候,需要加上{ root: true }
    const accessRoutes = await dispatch('permission/generateRoutes', roles, { root: true })
    // 动态添加可访问的路由
    router.addRoutes(accessRoutes)
    // 重置已访问视图和缓存视图
    dispatch('tagsView/delAllViews', null, { root: true })
  }
}

export default {
//添加 namespaced: true 的方式使其成为带命名空间的模块
  namespaced: true,
  state,
  mutations,
  actions
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值