Vue+Element UI 权限管理(角色 )

这篇具有很好参考价值的文章主要介绍了Vue+Element UI 权限管理(角色 )。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

用户前台登录后,后台返回一个token,将该token存储到store中,并设置到header中,每次发起请求时都会携带该token,用于后台进行权限校验

// 登录方法 login.vue
 handleLogin() {
      this.$refs.loginForm.validate((valid) => {
        if (valid) {
          this.loading = true;
          this.$store
            .dispatch("user/login", this.loginForm)
            .then(() => {
              this.$router.push({ path: this.redirect || "/" });
              this.loading = false;
            })
            .catch(() => {
              this.loading = false;
            });
        } else {
          console.log("error submit!!");
          return false;
        }
      });
    },

在store 的user.js中定义了该方法

 login({ commit }, userInfo) {
    const { userName, userPassword } = userInfo;
    return new Promise((resolve, reject) => {
      login({ userName: userName.trim(), userPassword: userPassword })
        .then((response) => {
          const { data } = response;
          commit("SET_TOKEN", data.token);
          setToken(data.token);
          resolve();
        })
        .catch((error) => {
          reject(error);
        });
    });
  },

const mutations = {
  RESET_STATE: (state) => {
    Object.assign(state, getDefaultState());
  },
  SET_TOKEN: (state, token) => {
    state.token = token;
  },
  SET_NAME: (state, name) => {
    state.name = name;
  },
  SET_AVATAR: (state, avatar) => {
    state.avatar = avatar;
  },
  SET_AUTHORITIES: (state, authorities) => {
    state.authorities = authorities;
  },
};

此时登录成功后,后台将返回一个token

element 权限管理,前端学习,vue.js,elementui

在请求拦截器中将token添加到请求头上,在响应拦截器中设置未登录状态访问时跳转到登录页面

import axios from "axios";
import { MessageBox, Message } from "element-ui";
import store from "@/store";
import { getToken, removeToken } from "@/utils/auth";
import router from "@/router";

// create an axios instance
const service = axios.create({
  baseURL: "http://localhost:8080", // url = base url + request url
  timeout: 5000, // request timeout
});

// request interceptor
service.interceptors.request.use(
  (config) => {
    if (store.getters.token) {
      config.headers["token"] = getToken();
    }
    return config;
  },
  (error) => {
    console.log(error);
    return Promise.reject(error);
  }
);

//  response 拦截器
service.interceptors.response.use(
  (response) => {
    const res = response.data;

    // if the custom code is not 20000, it is judged as an error.
    if (res.code !== 200 && res.code !== 201) {
      Message({
        message: res.message || "Error",
        type: "error",
        duration: 5 * 1000,
      });

      // 50008: Illegal token; 50012: Other clients logged in; 50014: Token expired;
      if (res.code === 50008 || res.code === 50012 || res.code === 50014) {
        // to re-login
        MessageBox.confirm(
          "You have been logged out, you can cancel to stay on this page, or log in again",
          "Confirm logout",
          {
            confirmButtonText: "Re-Login",
            cancelButtonText: "Cancel",
            type: "warning",
          }
        ).then(() => {
          store.dispatch("user/resetToken").then(() => {
            location.reload();
          });
        });
      }
      if (res.code == 401) {
        removeToken();
        router.replace({
          path: "/login",
        });
      }
      return Promise.reject(new Error(res.message || "Error"));
    } else {
      return res;
    }
  },
  (error) => {
    console.log("err" + error); // for debug
    Message({
      message: error.message,
      type: "error",
      duration: 5 * 1000,
    });
    return Promise.reject(error);
  }
);

export default service;

 在permission.js 中进行相关代码编写 (获取用户的信息,动态路由的生成加载)

 router.beforeEach()路由拦截()

import router from "./router";
import store from "./store";
import { Message } from "element-ui";
import NProgress from "nprogress"; // progress bar
import "nprogress/nprogress.css"; // progress bar style
import { getToken } from "@/utils/auth"; // get token from cookie
import getPageTitle from "@/utils/get-page-title";

NProgress.configure({ showSpinner: false }); // NProgress Configuration

const whiteList = ["/login"]; // no redirect whitelist

router.beforeEach(async (to, from, next) => {
  // start progress bar
  NProgress.start();

  // set page title
  document.title = getPageTitle(to.meta.title);

  // determine whether the user has logged in
  const hasToken = getToken();
  const hasRoles =
    store.state.user.authorities && store.state.user.authorities.length > 0;
  // 如果有token再跳转到登录页面时,根据获取的角色信息进行页面跳转
  if (hasToken) {
    if (to.path === "/login") {
      if (store.state.user.authorities) {
        if (store.state.user.authorities.includes("ROLE_ADMIN")) {
          next({ path: "/" });
        } else {
          next({ path: "/user" });
        }
      } else {
        next({ path: "/" });
      }
      NProgress.done();
    } else {
      // 获取登录用户名 如果用户名存在说明用户已经登录且获得了用户信息,直接放行,如果没有用户名,就进行用户信息获取
      const hasGetUserInfo = store.getters.name;
      if (hasGetUserInfo) {
        next();
      } else {
        try {
          //判断用户角色是否存在
          if (!hasRoles) {
            let userInfo = await store.dispatch("user/getInfo"); // 获取用户信息
            // 根据获得到的用户信息,获取用户角色信息并动态生成路由
            let routes = await store.dispatch(
              "permission/getAsyncRoutes",
              userInfo.user.authorities
            );
            router.options.routes = routes;
            router.addRoutes(routes); // 将生成的动态路由添加到原先的路由中
            next({ ...to, replace: true }); // 保证路由已挂载

            // 根据用户角色进行登录后的首页面跳转
            if (store.state.user.authorities) {
              if (store.state.user.authorities.includes("ROLE_ADMIN")) {
                next({ path: "/" });
              } else {
                next({ path: "/user/user" });
              }
            }
          }
        } catch (error) {
          // remove token and go to login page to re-login
          await store.dispatch("user/resetToken");
          Message.error(error || "Has Error");
          next(`/login`);
          NProgress.done();
        }
      }
    }
  } else {
    /* has no token*/
    if (whiteList.indexOf(to.path) !== -1) {
      // in the free login whitelist, go directly
      next();
    } else {
      // other pages that do not have permission to access are redirected to the login page.
      next(`/login`);
      NProgress.done();
    }
  }
});

router.afterEach(() => {
  // finish progress bar
  NProgress.done();
});

获取用信息的方法定义在store的user.js中

  // 获取用户信息
  getInfo({ commit, state }) {
    return new Promise((resolve, reject) => {
      getInfo()
        .then((response) => {
          const { data } = response;
          if (!data) {
            return reject("Verification failed, please Login again.");
          }
          const { username, authorities } = data.user;
          // 将用户名,和用户角色信息存储到store中
          commit("SET_NAME", username); 
          commit("SET_AUTHORITIES", authorities);
          resolve(data);
        })
        .catch((error) => {
          reject(error);
        });
    });
  },

在store 的 permission.js 为动态路由的相关方法和存储 

import { asyncRoutes, constantRoutes } from "@/router";
/**
 * 通过meta中的roles信息判断用户是否有权限
 * @param roles
 * @param route
 */
function hasPermission(roles, route) {
  if (route.meta && route.meta.roles) {
    return roles.some((role) => route.meta.roles.includes(role));
  } else {
    return true;
  }
}

/**
 * 根据角色和配置生成当前用户的路由
 * @param {array} routes 配置的路由
 * @param {array} roles 用户角色
 */
let GenerateRoutes = (routes, roles) => {
  let res = [];
  routes.forEach((route) => {
    const tmp = { ...route };

    if (hasPermission(roles, tmp)) {
      if (tmp.children) {
        tmp.children = GenerateRoutes(tmp.children, roles);
      }
      // console.log(tmp);
      res.push(tmp);
    }
  });

  return res;
};

const getDefaultState = () => {
  return {
    roles: [],
    routes: constantRoutes, // 用于配置页面导航等
  };
};
const state = getDefaultState();
const mutations = {
  SET_ROLES: (state, roles) => {
    state.roles = roles;
  },
  SET_ROUTES: (state, routes) => {
    state.routes = routes;
  },
};

const actions = {
  /**根据角色获取路由配置 */
  getAsyncRoutes({ commit }, roles) {
    let filterRoutes = GenerateRoutes(asyncRoutes, roles);
    let res = constantRoutes.concat(filterRoutes);
    commit("SET_ROUTES", res);
    return res;
  },
};

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

将新增的js文件引入store的index.js文件中

import Vue from "vue";
import Vuex from "vuex";
import getters from "./getters";
import app from "./modules/app";
import settings from "./modules/settings";
import user from "./modules/user";
import permission from "./modules/permission"; 

Vue.use(Vuex);

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

export default store;

路由文件

import Vue from "vue";
import Router from "vue-router";

Vue.use(Router);

/* Layout */
import Layout from "@/layout";

// 默认路由
export const constantRoutes = [
  {
    path: "/login",
    component: () => import("@/views/login/index"),
    hidden: true,
  },
  {
    path: "/404",
    component: () => import("@/views/404"),
    hidden: true,
  },
];
// 自定义动态路由,在meta中添加了roles,通过roles中是角色进行动态生成不同角色的动态路由
export const asyncRoutes = [
  {
    path: "/",
    component: Layout,
    redirect: "/employee",
    meta: { roles: ["ROLE_ADMIN"] },
    children: [
      {
        path: "employee",
        name: "Employee",
        component: () => import("@/views/employee/index"),
        // meta: { title: "员工管理", icon: "el-icon-s-custom" },
        meta: {
          roles: ["ROLE_ADMIN"],
          title: "员工管理",
          icon: "el-icon-s-custom",
        },
      },
    ],
  },
 {
    path: "/user",
    component: Layout,
    meta: { roles: ["ROLE_DEPT", "ROLE_EMP"] },
    children: [
      {
        path: "user",
        name: "User",
        component: () => import("@/views/user/index"),
        meta: {
          roles: ["ROLE_DEPT", "ROLE_EMP"],
          title: "个人信息",
          icon: "el-icon-setting",
        },
      },
    ],
  },
// 404 page must be placed at the end !!!
  { path: "*", redirect: "/404", hidden: true },
];

const createRouter = () =>
  new Router({
    // mode: 'history', // require service support
    scrollBehavior: () => ({ y: 0 }),
    routes: constantRoutes,
  });

const router = createRouter();

// Detail see: https://github.com/vuejs/vue-router/issues/1234#issuecomment-357941465
export function resetRouter() {
  const newRouter = createRouter();
  router.matcher = newRouter.matcher; // reset router
}

export default router;

 此时登录成功并获取到用户信息后,可在控制台看到存储到store中的信息

element 权限管理,前端学习,vue.js,elementui

 登录成功界面实例

管理员

element 权限管理,前端学习,vue.js,elementui

部门经理

element 权限管理,前端学习,vue.js,elementui

基本员工文章来源地址https://www.toymoban.com/news/detail-518902.html

到了这里,关于Vue+Element UI 权限管理(角色 )的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Vue + Element UI 前端篇(八):管理应用状态

    1. 引入背景 像先前我们是有导航菜单栏收缩和展开功能的,但是因为组件封装的原因,隐藏按钮在头部组件,而导航菜单在导航菜单组件,这样就涉及到了组件收缩状态的共享问题。收缩展开按钮触发收缩状态的修改,导航菜单需要根据收缩状态来设置导航栏的宽度。这样就

    2024年02月09日
    浏览(43)
  • 管理系统的前端模板(vue2+Element UI)

    目录 前言 一、模板展示图 二、获取的方式及操作运行步骤  (一)获取方式 (二)操作步骤  1.下载安装node.js  2.下载完成解压缩后在idea的里面打开终端。 3.输入下载相关依赖的命令 4.运行项目的命令 5.然后把给到的地址浏览器打开就可以了  三、代码的展示(这个点的内

    2024年02月05日
    浏览(45)
  • 【前端】Vue+Element UI案例:通用后台管理系统-面包屑、tag栏

    参考视频: VUE项目,VUE项目实战,vue后台管理系统,前端面试,前端面试项目 案例 链接 【前端】Vue+Element UI案例:通用后台管理系统-导航栏(视频p1-16) https://blog.csdn.net/karshey/article/details/127640658 【前端】Vue+Element UI案例:通用后台管理系统-Header+导航栏折叠(p17-19) http

    2024年02月09日
    浏览(57)
  • Vue3+Vue-Router+Element-Plus根据后端数据实现前端动态路由——权限管理模块

    提示:文章内容仔细看一些,或者直接粘贴复制,效果满满 提示:文章大概 1、项目:前后端分离 2、前端:基于Vite创建的Vue3项目 3、后端:没有,模拟的后端数据 4、关于路径“@”符号——vite.config.js 文件里修改 提示:以下是本篇文章正文内容,下面案例可供复制粘贴使用

    2024年02月02日
    浏览(38)
  • 前端Vue:权限管理,给角色分配权限

    👉前端-Vue权限控制,菜单权限,按钮权限_一人创客的博客-CSDN博客 目录 介绍: 前端权限的概念: 前端权限的意义: Vue权限管理的代码实现: 菜单 刷新界⾯菜单消失 标识⽤户名, ⽅便查看当前⽤户 退出登陆:  界面: 1.判断当前是否登陆 2.控制是否可以访问角色界面 (

    2024年02月11日
    浏览(25)
  • (vue权限管理)前端路由表角色权限管理,通过登录不同角色侧边栏显示对应页面

    1. 首先在src/router/index.js中添加路由表,其中constantRoutes 设置的为所有角色可见的路由,asyncRouterMap为对应权限人员可见路由,demo路由表代码如下: 2.在src/api/user.js中创建用户登录,获取用户信息,以及登出的接口 3.在store/modules/user.js文件,添加获取角色权限role的信息 4.在src

    2024年02月11日
    浏览(32)
  • 【Vue2+Element ui通用后台】菜单权限

    对于菜单权限我们需要解决以下问题: 1、不同的账号登录,有不同的菜单 2、通过输入url地址来显示页面,所以应该根据权限动态注册路由 3、对于菜单数据,在不同页面之间的数据通信 现在项目中的菜单,我们是在 CommenAside 中写死的,现在我们需要根据登录后返回的权限

    2024年02月07日
    浏览(24)
  • 基于vue-cli创建后台管理系统前端页面——element-ui,axios,跨域配置,布局初步,导航栏

    1.vue-cli创建前端工程,安装element-ui,axios和配置; 2.前端跨域的配置,请求添加Jwt的设置; 3.进行初始化布局,引入新增页面的方式; 4.home页面导航栏的设置,一级目录,二级目录; 安装成功 布局初步 1.vue-cli创建前端工程,安装element-ui,axios和配置; 2.前端跨域的配置,请

    2024年02月09日
    浏览(41)
  • ​Vue + Element UI前端篇(二):Vue + Element 案例 ​

    打开 Visual Studio Code,File -- add Folder to Workspace,导入我们的项目。 安装依赖 Element 是国内饿了么公司提供的一套开源前端框架,简洁优雅,提供了 vue、react、angular 等多个版本,我们这里使用 vue 版本来搭建我们的界面。 访问:http://element-cn.eleme.io/#/zh-CN/component/installation ,官

    2024年02月09日
    浏览(30)
  • 78.(前端)分配权限页面显示——树形结构使用(Element-ui的Tree树形控件)

    在前端的操作中,应该增加修改、删除、分配权限的操作 这次主要是实现分配权限的显示!!!!!! 更换icon图标,并设计大小 绑定函数,点击弹出提示框(DIalog对话框) 在对话框内,应该显示一个树形结构提供选择(Tree树形控件) 初始化树形结构,并填充数据

    2024年02月05日
    浏览(38)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包