vue-element-admin 初次使用配置

初次使用 vue-element-admin 进行项目的编写,本人也是才疏学浅踩了很多的坑,特此记录一下更改了哪些配置,方便下一次的使用。

URL的配置

  • 这里涉及到的是 .env.development 文件 和 .env.production 文件 将这两个文件的 VUE_APP_BASE_API 设置为自己项目的 BaseURL。
.env.development 文件

   # just a flag
   ENV = 'development'

   # base api
   VUE_APP_BASE_API = '/dev-api'
   
.env.production 文件

   # just a flag
   ENV = 'production'

   # base api
   VUE_APP_BASE_API = '/prod-api'

登录

  • 登录中的流程是这样的 首先 在view/login/index.vue 下我们可以根据 @click.native.prevent="handleLogin"
      <el-button :loading="loading" type="primary" style="width:100%;margin-bottom:30px;" @click.native.prevent="handleLogin">Login</el-button>

  • 找到登录方法 handleLogin
handleLogin() {
     this.$refs.loginForm.validate(valid => {
       if (valid) {
         this.loading = true
         // 请求 store 中的方法
         this.$store.dispatch('user/login', this.loginForm) // 会到src/store/modules/user.js中请求Login方法。
           .then(() => {
             this.$router.push({ path: this.redirect || '/', query: this.otherQuery })
             this.loading = false
           })
           .catch(() => {
             this.loading = false
           })
       } else {
         console.log('error submit!!')
         return false
       }
     })
   },
  • 通过上方代码的注释 大家也可以看出 接下来我们到 src/store/modules/user.js 找到 lgin 方法
// user login 代码为适应自己的项目跟源码有所不同 以下代码皆是如此
 login({ commit }, userInfo) {
   const { username, password } = userInfo
   return new Promise((resolve, reject) => {
     // login({ userName: username.trim(), userPwd: password })
     login(username.trim(), password).then(response => {
       console.log('用户登录了');
       console.log(response);
       const {obj} = response
       console.log(obj);
       commit('SET_TOKEN', obj)
       setToken(obj)
       resolve()
     }).catch(error => {
       reject(error)
     })
   })
 },
  • 此时我们通过上方的代码继续找到 login 的请求 在 src/api/user.js 下
export function login(userName, userPwd) {
  return request({
    url: '/User/Login',
    method: 'post',
    params: {
      userName,
      userPwd
    }
  })
}
  • 这时我们就通过 login 的请求获取到了 token 然后我们就需要通过 token 来获取用户的信息
export function getInfo(token) {
  return request({
    url: '/User/info',
    method: 'get',
    params: { token }
  })
}
  • 我的这个项目涉及到了权限登录 所以我需要在 src/permission.js 中进行用户权限的设置
  // 如果有 token 也就是已经登录的情况下
  if (hasToken) {
    if (to.path === '/login') {
      // 并且要前往的路径是 '/login' 则返回 '/'
      // if is logged in, redirect to the home page
      next({ path: '/' })
      NProgress.done() // hack: https://github.com/PanJiaChen/vue-element-admin/pull/2939
    } else {
      // 从store中取得用户的 roles, 也就是用户的权限 并且用户的权限数组必须有一个以上
      // determine whether the user has obtained his permission roles through getInfo
      const hasRoles = store.getters.roles && store.getters.roles.length > 0
      // 有权限的话就直接进入
      if (hasRoles) {
        next()
      } else {
        // 没有权限
        try {
          // get user info // 获取用户信息
          // note: roles must be a object array! such as: ['admin'] or ,['developer','editor']
          const userInfo = await store.dispatch('user/getInfo')
		  /*
		  	在这个地方获取信息并进行判断 从获取到的所有信息userInfo 中获取 角色值 或者进行判断
			要注意 roles 一定要是一个数组 这涉及到 之后的 .some() 方法
		  */

          // generate accessible routes map based on roles
          // 生成可访问路由
          const accessRoutes = await store.dispatch('permission/generateRoutes', roles)

          // dynamically add accessible routes
          // 将可访问路由添加到路由上
          router.addRoutes(accessRoutes)

          // hack method to ensure that addRoutes is complete
          // set the replace: true, so the navigation will not leave a history record
          // 进入路由
          next({ ...to, replace: true })
        } catch (error) {
          // 如果出现异常  清空路由 
          // remove token and go to login page to re-login
          await store.dispatch('user/resetToken')
          // Message提示错误
          Message.error(error || 'Has Error')
          // 跳到login页面重新登陆
          next(`/login?redirect=${to.path}`)
          NProgress.done()
        }
      }
    }
  } else {
    /* has no token*/
    // 没有token 也就是没有登陆的情况下  
    // 判断是否是白名单(也就是说不需要登陆就可以访问的路由)
    if (whiteList.indexOf(to.path) !== -1) {
      // in the free login whitelist, go directly
      next()
    } else {
      // 其他的一律给我跳到login页面 进行登陆
      // other pages that do not have permission to access are redirected to the login page.
      next(`/login?redirect=${to.path}`)
      NProgress.done()
    }
  }
})
  • 这个地方涉及到一点 将以下代码 复制到自己创建在 src/store/modules/permission.js 页面下 (以下代码来自于 vue-element-admin 项目的源码)
import { asyncRoutes, constantRoutes } from '@/router'

/**
 * Use meta.role to determine if the current user has permission
 * @param roles
 * @param route
 */
// 判断是否有权限
function hasPermission(roles, route) {
  if (route.meta && route.meta.roles) {
    // roles.some => Array.some 相当于是只要有一个满足就为true 
    // 判断用户的权限于当前路由访问所需要的权限是否有一个满足
    // 比如说用户权限为 ['one','two']  当前路由访问所需要权限为 ['two','three']  那么就说明当前用户可以访问这个路由
    return roles.some(role => route.meta.roles.includes(role))
  } else {
    // 默认是可访问的
    return true
  }
}

/**
 * Filter asynchronous routing tables by recursion
 * 递归过滤异步路由表,返回符合用户角色权限的路由表
 * @param routes asyncRoutes
 * @param roles
 */
// 生成可访问路由
export function filterAsyncRoutes(routes, roles) {
  const res = []

  routes.forEach(route => {
    const tmp = { ...route }
    // 判断当前路由是否可以访问
    if (hasPermission(roles, tmp)) {
      // 如果当前路由还有子路由
      if (tmp.children) {
        // forCheck() 方法递归判断该节点下是否存在页面,不存在则隐藏
        // true:不存在,false:存在
        tmp.children = filterAsyncRoutes(tmp.children, roles)
      }
      // 将可访问路由放入数组中
      res.push(tmp)
    }
  })
 // 返回
  return res
}

const state = {
  routes: [],
  addRoutes: []
}

// 为什么要写这里呢,因为后面的Sidebar组件与这个环环相扣
const mutations = {
  SET_ROUTES: (state, routes) => {
    // 添加的路由
    state.addRoutes = routes
    // 将vuex中的路由进行更新
    state.routes = constantRoutes.concat(routes)
  }
}

const actions = {
  generateRoutes({ commit }, roles) {
    return new Promise(resolve => {
      let accessedRoutes
      // 如果roles包含 'admin' 直接可以全部访问
      if (roles.includes('admin')) {
        accessedRoutes = asyncRoutes || []
      } else {
        // 利用 filterAsyncRoutes 过滤出可访问的路由
        accessedRoutes = filterAsyncRoutes(asyncRoutes, roles)
      }
      // 保存可访问的路由到store中
      commit('SET_ROUTES', accessedRoutes)
      // 将可访问路由返回
      resolve(accessedRoutes)
    })
  }
}

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

  • 同时不要忘记在 src/store/index.js 进行引入
import Vue from 'vue'
import Vuex from 'vuex'
import getters from './getters'
import app from './modules/app'
import permission from './modules/permission' // 引入
import settings from './modules/settings'
import user from './modules/user'

Vue.use(Vuex)

const store = new Vuex.Store({
  modules: {
    app,
    settings,
    permission, // 补充
    user
  },
  getters
})

export default store

权限路由的问题

  • 这里也是最重要的一点当我添加权限路由的时候,明明已经有了权限路由的数组 但是就是不显示权限数组 我查询了很多资料也没有解决 所以在这里记录一下 首先按照如下的方式来将 src/layout/components/index.vue 中按照如下进行更改。
export default {
 components: { SidebarItem, Logo },
 computed: {
   ...mapGetters([
     'sidebar',
     'permission_routes'
   ]),
   // routes() {
   //   return this.$router.options.routes
   // },
   activeMenu() {
     const route = this.$route
     const { meta, path } = route
     // if set path, the sidebar will highlight the path you set
     if (meta.activeMenu) {
       return meta.activeMenu
     }
     return path
   },
   showLogo() {
     return this.$store.state.settings.sidebarLogo
   },
   variables() {
     return variables
   },
   isCollapse() {
     return !this.sidebar.opened
   }
 }
}
  • 之后我们在 src/store/getters.js 中 添加如下代码 这样 权限路由就能显示了
permission_routes: state => state.permission.routes,
  • 以上只是对自己遇到问题的一些记录方便日后的查找
posted @ 2021-08-04 11:01  z1n4q2  阅读(566)  评论(0)    收藏  举报