乐趣区

关于前端:Vue权限路由菜单权限按钮权限控制

前言

   年前竣工了做了半年的铁路后盾管理系统,零碎整体业务比较复杂,这也是我到公司从 0 到 1 的 一个残缺零碎实际,做这个零碎过程中踩了不少坑,也学到了很多。

  做完这个零碎没多久,紧接着又一个零碎来了,没及时总结,羞愧哈!其实咱们在做的后盾管理系统大多数根底框架都一样,后盾管理系统 次要的 是 角色权限治理 按钮权限治理 菜单治理,其它的业务次要围绕在这个根底之上进行扩大,最终 形成了 合乎业务的后盾管理系统.

 因为我司的我的项目都是采纳 Vue 技术栈,那么该文章也是解说 Vue 如何进行权限治理 进行解说。

结尾有彩蛋哦!

权限受权登录

任何一个后盾管理系统都是 首先从登录开始,登录后返回用户根本信息,以及 token。

  • token:存入 sessionStronge / localStronge 中,而后退出到 封装好的 Axios 的 申请头中,每次申请携带 token.
  • 用户根本信息

登录胜利后同时要做很多事件,具体业务具体看待。后盾管理系统 登录胜利后会申请以后用户的菜单权限接口,来获取用户的可拜访的路由(动静路由),获取胜利后, Vue Router 是不能间接应用的,必须得解析成合乎 Vue Router 可辨认的格局 .

登录

    handleLogin() {
      this.$refs.loginForm.validate(valid => {if (valid) {
          this.loading = true;
          login(this.loginForm)
            .then(res => {if (res.code === 200) {
                // 寄存 token
                sessionStorage.setItem("tokens", res.data.token);
                // 触发 Vuex 来 加载 获取以后用户的菜单,并解析路由
                store.dispatch("setMenuList");
                this.$message({
                  message: "登录胜利",
                  type: "success",
                  duration: 1000
                });
                this.$router.replace({path: "/dashboard"});
              }
            })
            .catch(() => {this.loading = false;});
        } else {console.log("error submit!!");
          return false;
        }
      });
    }

获取以后用户菜单,解析路由

登录胜利后,本文通过 Vuex 来获取以后用户菜单和解析路由的。

store.dispatch("setMenuList");

/*
 * @Description: 
 * @Author: ZhangXin
 * @Date: 2021-02-02 16:10:59
 * @LastEditTime: 2021-02-23 23:03:30
 * @LastEditors: ZhangXin
 */
// getMenu 解析后盾路由
import {getMenu} from '../../utils/getMenu'
// 引入路由 和 动态路由
import router, {constantRoutes} from '../../router/index'
const state = {
  routerType: '',
  // 菜单路由
  meunList: []}

const mutations = {SET_ROUTER_TYPE(state, type) {state.routerType = type},
  SET_ROUTER_MENULIST(state, list) {
    // 动态路由 +  动静路由  合并  残缺路由
    const array = constantRoutes.concat(list)
    state.meunList = array
    router.options.routes = array
    router.addRoutes([...array])
  }
}

const actions = {setMenuList({ commit, state}) {
    // 接管返回来的 路由数组
    return new Promise((resolve, reject) => {getMenu().then(res => {commit('SET_ROUTER_TYPE', '')
        commit('SET_ROUTER_MENULIST', res)
        resolve(res)
      })
    })
  }
}
export default {
  state,
  mutations,
  actions
}

解析后端返回来路由(重点)

封装好的解析后端返回来的路由,这块次要是为了在 Vuex 中应用。

/*
 * @Description: 
 * @Author: ZhangXin
 * @Date: 2021-02-02 16:03:48
 * @LastEditTime: 2021-02-23 23:09:02
 * @LastEditors: ZhangXin
 */
import Layout from '@/layout'
import {getUserAuthMenu} from '@/api/user'



/**
 * @description: 解析后端返回来的菜单树
 * @param {*} data 后端返回来的路由树
 * @param {*} arr 菜单
 * @return {*}
 */
function tree(data, arr) {data.forEach((datas, index) => {
    arr.push({
      path: datas.path,
      name: datas.name,
      types: datas.types,
      hidden: datas.hidden == 'true' ? true : false,
      // 过后这块踩坑了
      component: datas.component === 'Layout' ? Layout : resolve => require([`@/views/${datas.component}.vue`], resolve),
      meta: {
        title: datas.meta.title,
        icon: datas.meta.icon,
        // 用来寄存按钮权限
        button: datas.meta.button
      },
      //  redirect: datas.redirect,
      id: datas.id,
      // 子路由
      children: []})

    if (datas.children) {const childArr = tree(datas.children, [])
      arr[index].children = childArr
    }
  })
  return arr
}


/**
 * @description: 获取以后登录用户的菜单
 * @param {*}
 * @return {*}
 */
export function getMenu() {return new Promise(function (resolve, reject) {getUserAuthMenu().then(res => {if(res.code === 200){
      const datas = res.data
      // 调用 tree 来解析后端返回来的树
      resolve(tree(datas, []))
      }

    })
  })
}

后端接管路由格局

前端接管到的实在菜单树

页面刷新,路由失落

到此为止,曾经实现了 Vue 动静权限管制,别快乐的太早,哈哈,一刷新页面,页面就进入了 404 页面

这是为什么呢?

因为存入 Vuex 中的数据,一刷新页面,就会清空,那么当然找不到以后路由,就进入 404 页面了 .

如何解决呢?

一、能够 将 动态和 动静 形成的残缺路由 寄存在 sessionStronge / localStronge 中,而后页面刷新时,通过在 全局入口文件 App.vue 的 生命周期 created 中,将 router = sessionStronge / localStronge 存入的残缺的路由,页面在刷新时,它会从新加载残缺的路由。

二、如果是应用 Vuex 来获取和解析用户菜单的话,那么你能够在全局入口文件 App.vue 的 生命周期 created 中,再次执行 Vuex Action 来从新加载用户菜单

我这块间接在 App.vue 的 生命周期 created 中 , 再次执行了 Vuex 来进行加载和解析,没有做其它操作。当然了,具体业务具体看待。

<template>
  <div id="app">
    <router-view v-if="isRouterAlive" />
  </div>
</template>

<script>
import store from "@/store";
export default {
  name: "App",
  provide() {
    return {reload: this.reload};
  },
  data() {
    return {isRouterAlive: true};
  },
  methods: {reload() {
      this.isRouterAlive = false;
      this.$nextTick(() => (this.isRouterAlive = true));
    }
  },
  created() {
      // 只有刷新页面,就会从新加载路由树,保障了路由不会失落数据
      store.dispatch("setMenuList");
  }
};
</script>

总结

核心思想

  • 1. 定义合乎 以后我的项目业务路由格局,前后端按这个接管传递
  • 2. 前端解析后端返回的动静路由,生成Vue Router 可辨认格局,最初拼接残缺路由
  • 3. 刷新路由失落解决

<br/>

按钮权限管制

  • 1. 以后组件 路由 携带可应用的 按钮权限,存入数组中,通过 v -if 来判断是否显示
  • 2. 登录时,独自获取整个零碎的按钮权限,将获取到的所有按钮 存入一个数组中,放入全局中,而后,通过 v-if 来判断是否显示
  • 3. …………

结语

❤️关注 + 点赞 + 珍藏 + 评论 + 转发❤️,原创不易,激励笔者创作更好的文章

关注公众号 前端自学社区,> 即可获取更多前端高质量文章!

关注后回复关键词“加群”,即可退出“前端自学交换群”,独特学习提高。

退出移动版