Vue权限路由[菜单权限/按钮权限控制]

海军 等级 584 4 1

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权限路由[菜单权限/按钮权限控制]

前端接收到的真实菜单树

Vue权限路由[菜单权限/按钮权限控制]

页面刷新,路由丢失

到此为止,已经实现了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.刷新路由丢失处理

按钮权限控制

  • 1.当前组件 路由 携带可使用的 按钮权限,存入数组中,通过v-if 来判断是否显示
  • 2.登录时,单独获取整个系统的按钮权限,将获取到的所有按钮 存入一个数组中,放入全局中,然后,通过 v-if 来判断是否显示
  • *3. ............ *

Vue权限路由[菜单权限/按钮权限控制]

Vue权限路由[菜单权限/按钮权限控制]

::: warning 关注微信公众号: 获取更多前端资讯 :::

收藏
评论区

相关推荐

【官宣】Vue 3.0 发布!
Vue 团队于 2020 年 9 月 18 日晚 11 点半发布了 Vue 3.0 版本,我们连夜对 Release 进行了翻译。由于时间仓促,文中如有翻译不当的地方还望提出。如有侵权,请联系删帖。以下为译文正文。 原文:https://github.com/vuejs/vuenext/releases 作者:Vue 团队 译文:https://zh
Android webview 与 js(Vue) 交互
js 与原生交互分为两种情况:js 调用原生方法,原生调用 js 方法。 本文将对这两种情况分别讲解,H5 端用 vue 实现。 一、前期准备(Vue项目准备) 本文的 H5 端用Vue 实现,所以在正式开始前先把 Vue 项目环境准备好。 项目写好后,执行 npm run serve 命令启动项目,启动成功后会在命令
Vue 组件通信方式及其应用场景总结
前言 相信实际项目中用过vue的同学,一定对vue中父子组件之间的通信并不陌生,vue中采用良好的数据通讯方式,避免组件通信带来的困扰。今天笔者和大家一起分享vue父子组件之间的通信方式,优缺点,及其实际工作中的应用场景 首先我们带着这些问题去思考 1 vue中到底有多少种父子组件通信方式? 2 vue中那种父子组件最佳通信方式是什么? 3
基于Vue实现一个有点意思的拼拼乐小游戏
笔者去年曾写过一个类似的拼拼乐小游戏,技术栈采用自己的Xuery框架和原生javascript实现的,脚手架采用gulp来实现,为了满足对vue的需求,笔者再次使用vue生态将其重构,脚手架采用比较火的vuecli。 前言 为了加深大家对vue的了解和vue项目实战,笔者采用vue生态来重构此项目,方便大家学习和探索。技术栈如下: vuecli4
了解Vuex状态管理模式
1 Vuex是什么呢?它是Vue的状态管理模式,在使用vue的时候,需要在vue中各个组件之间传递值是很痛苦的,在vue中我们可以使用vuex来保存我们需要管理的状态值,值一旦被改变,所有引用该值的地方就会自动更新。是不是很方便,很好用呢? vuex是专门为vue.js设计的状态管理模式,集中式存储和管理应用程序中所有组件的状态,vuex也集成了vue的
史上最全前端面试题(但是没有答案 自己百度 手动狗头!)
Vue面试题 生命周期函数面试题 1.什么是 vue 生命周期 2.vue生命周期的作用是什么 3.第一次页面加载会触发哪几个钩子 4.简述每个周期具体适合哪些场景 5.created和mounted的区别 6.vue获取数据在哪个周期函数 7.请详细说下你对vue生命周期的理解? vue路由面试题 1.mvvm 框架是什么? 2.vuerout
Vue入门系列之Vue实例详解与生命周期
Vue的实例是Vue框架的入口,其实也就是前端的ViewModel,它包含了页面中的业务逻辑处理、数据模型等,当然它也有自己的一系列的生命周期的事件钩子,辅助我们进行对整个Vue实例生成、编译、挂着、销毁等过程进行js控制。 5.1. Vue实例初始
前端技术栈:5分钟入门VUE+Element UI
目录前端技术栈:5分钟入门VUEElement UI前言2021了,VUE都出3.0了,还不开始学习VUE?那不是一个全栈攻城狮的自我修养,虽然VUE出3.0了,但是入门还是建议VUE2.0 Element UI,毕竟3.0还要等养肥了在学,现在教程太少,学习2.0之后在学3.0也能更加理解为什么要这么去改进VUE是啥?简单来说就是
介绍 | Vue3中文文档
已经了解 Vue 2,只想了解 Vue 3 的新功能可以参阅 Vue.js 是什么Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与以及各种 结合使用时
30 道 Vue 面试题,内含详细讲解(涵盖入门到精通,自测 Vue 掌握程度)
30 道 Vue 面试题,内含详细讲解(涵盖入门到精通,自测 Vue 掌握程度)(https://www.zhihu.com/people/huobodexiaobaiyang).css1cd9gw4{marginleft:.3em;}545 人赞同了该文章前言
Vue 3 计划放弃支持 IE11
Vue.js 作者尤雨溪就 Vue 3 支持 IE11 的计划提交了新提案。提案摘要:1. Vue 3 将不会支持 IE11 2. 原定投入 Vue 3 IE11 支持的精力将投入给 2.7,移植 3.x 兼容的新功能,包括: Composition API \<script setup\ 以及其它新的单文件组件特性
npm发布包以及更新包还有需要注意的几点问题(这里以发布vue插件为例)
前言在此之前,你需要去npm官网注册一个属于自己的账号,记住自己的账户名以及密码、邮箱,后面会用的到。第一步,安装webpack简易框架vue init webpacksimple marquee 这里会用到vue init 命令,如果你的cli版本是3或者以上,那么在此之前你需要安装vue/cliinit npm install g @vue
Vue 3.0 有哪些新特性值得我们提前了解
一、迎接 Vue 3.0 1\. 简介在这里插入图片描述Vue.js 作者兼核心开发者尤雨溪宣布 Vue 3.0 进入 Beta 阶段。 已合并所有计划内的 RFC 已实现所有被合并的 RFC Vue CLI 现在通过 vueclipluginvuenext 提供了实验性支持 2\. 新特性重点关注: 更快更省
Vue 从安装到创建项目
1.安装Node可以直接在官网中下载安装默认自动安装Node和NPM(Node Package Manager) 完成后检查安装版本:node v npm v2.安装webpack webpack全局安装npm install webpack g3.安装vue脚手架 全局安装脚手架3npm install @vue/cli g 备注
vue项目无配置文件解决方案
问题在开发vue项目时,需要重新设置项目的启动端口,发现项目目录中并没有相关的配置文件【config目录】vue脚手架版本【通过vue version查询】:@vue/cli 4.5.13解决方案在vue项目根目录下创建vue.config.js配置文件vue.config.jsmodule.exports devServer: d