• CLWY权限管理(六)--- 权限实现


    修改路由文件

    src/router/index.js

    import Vue from "vue";
    import VueRouter from "vue-router";
    import Layout from "@/views/layout/IndexView";
    
    Vue.use(VueRouter);
    
    const routes = [
      {
        path: "/sign_in",
        component: () => import("@/views/auth/SignIn"),
        meta: { title: "登录" },
      },
      // 无权限访问
      {
        path: "/401", 
        component: () => import("@/views/error-page/Page401View"),
        meta: { title: "401" },
      },
      {
        path: "/",
        component: Layout,
        children: [
          {
            path: "",
            component: () => import("@/views/HomeView"),
            meta: { title: "首页" },
          },
          {
            path: "/users",
            component: () => import("@/views/users/ListView"),
            meta: { title: "用户列表" },
          },
          {
            path: "/users/create",
            component: () => import("@/views/users/CreateView"),
            meta: { title: "新增用户" },
          },
          {
            path: "/users/edit/:id",
            component: () => import("@/views/users/EditView"),
            meta: { title: "编辑用户" },
          },
          {
            path: "/roles",
            component: () => import("@/views/roles/ListView"),
            meta: { title: "用户组列表" },
          },
          {
            path: "/roles/create",
            component: () => import("@/views/roles/CreateView"),
            meta: { title: "新增用户组" },
          },
          {
            path: "/roles/edit/:id",
            component: () => import("@/views/roles/EditView"),
            meta: { title: "编辑用户组" },
          },
          {
            path: "/permissions",
            component: () => import("@/views/permissions/ListView"),
            meta: { title: "菜单与权限列表" },
          },
        ],
      },
    ];
    
    const router = new VueRouter({
      mode: "history",
      base: process.env.BASE_URL,
      routes,
    });
    
    export default router;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73

    创建401组件

    新建 views/error-page/Page401View.vue

    <template>
      <div class="errPage-container">
        <el-button icon="el-icon-arrow-left" class="pan-back-btn" @click="back">
          返回
        el-button>
        <el-row>
          <el-col :span="12">
            <h1 class="text-jumbo text-ginormous">Oops!h1>
            <h2>你没有权限去该页面h2>
            <ul class="list-unstyled">
              <li>或者你可以去:li>
              <li class="link-type">
                <router-link to="/"> 回首页 router-link>
              li>
            ul>
          el-col>
        el-row>
      div>
    template>
    
    <script>
    export default {
      name: "Page401View",
      methods: {
        back() {
          this.$router.go(-1);
        },
      },
    };
    script>
    
    <style lang="scss" scoped>
    .errPage-container {
      width: 800px;
      max-width: 100%;
      margin: 100px auto;
    
      .pan-back-btn {
        background: #008489;
        color: #fff;
        border: none !important;
      }
    
      .pan-gif {
        margin: 0 auto;
        display: block;
      }
    
      .pan-img {
        display: block;
        margin: 0 auto;
        width: 100%;
      }
    
      .text-jumbo {
        font-size: 60px;
        font-weight: 700;
        color: #484848;
      }
    
      .list-unstyled {
        font-size: 14px;
    
        li {
          padding-bottom: 5px;
        }
    
        a {
          color: #008489;
          text-decoration: none;
    
          &:hover {
            text-decoration: underline;
          }
        }
      }
    }
    style>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78

    创建permission状态管理器

    1、新建 store/modules/permission.js

    // 1、定义 state 用于存储 routers 路由列表
    const state = () => ({
      routers: [],
    });
    
    // 2、定义 mutations 用于修改路由列表数据
    const mutations = {
      SET_ROUTERS: (state, routers) => {
        state.routers = routers;
      },
    };
    
    // 3、定义 actions 用于获取路由数据
    const actions = {};
    
    // 4、导出
    export default {
      namespaced: true,
      state,
      mutations,
      actions,
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    2、修改 src/store/index.js 代码

    import Vue from "vue";
    import Vuex from "vuex";
    import auth from "./modules/auth";
    import permission from "./modules/permission"; // 1、导入 permission
    import getters from "@/store/getters";
    
    Vue.use(Vuex);
    
    export default new Vuex.Store({
      getters,
      modules: {
        auth,
        permission, // 2、注册 permission
      },
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    动态生成路由

    1、修改 src/permission.js 代码

    import router from "@/router";
    import { getToken } from "@/utils/auth";
    import store from "./store";
    import { Message } from "element-ui";
    
    router.beforeEach(async (to, from, next) => {
      document.title = `${to.meta.title} - 长乐未央`;
    
      const hasToken = getToken();
      if (hasToken) {
        if (to.path === "/sign_in") {
          next({ path: "/" });
        } else {
          try {
            // 1、判断路由是否已经生成了
            const hasRouters =
              store.getters.routers && store.getters.routers.length > 0;
            // console.log(111, hasRouters);
            if (hasRouters) {
              next();
            } else {
              // 2、如果还没有路由,读取接口,获取路由列表数据
              const { routers } = await store.dispatch("auth/getInfo");
              // console.log(222, routers);
              // 3、通过获取到的routers数据,去请求 modules/permission/generateRouters 函数,并传入 routers 路由数据
              await store.dispatch("permission/generateRouters", routers);
            }
          } catch (error) {
            await store.dispatch("auth/resetToken");
            Message.error(error || "Has Error");
            next("/sign_in");
          }
        }
      } else {
        if (to.path === "/sign_in") {
          next();
        } else {
          next("/sign_in");
        }
      }
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    请添加图片描述

    请添加图片描述

    2、修改 store/modules/permission.js

    const state = () => ({
      routers: [],
    });
    
    const mutations = {
      SET_ROUTERS: (state, routers) => {
        state.routers = routers;
      },
    };
    
    const actions = {
      // 4、定义 generateRouters 函数,接收两个参数。commit用于提交mutations修改数据;routers是传过来的路由列表
      generateRouters({ commit }, routers) {
        console.log(commit);
        console.log(333, routers);
      },
    };
    
    export default {
      namespaced: true,
      state,
      mutations,
      actions,
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    请添加图片描述

    3、继续修改 store/modules/permission.js

    import Layout from "@/views/layout/IndexView"; // 6、导入布局模板
    const state = () => ({
      routers: [],
    });
    
    const mutations = {
      SET_ROUTERS: (state, routers) => {
        state.routers = routers;
      },
    };
    
    const actions = {
      // 4、定义 generateRouters 函数,接收两个参数。commit用于提交mutations修改数据;routers是传过来的路由列表
      generateRouters({ commit }, routers) {
        console.log(commit);
        // console.log(333, routers);
        // 5、组装路由列表格式
        const accessedRouters = {
          path: "/",
          component: Layout,
        };
    
        // 7、循环取出路由列表所需的参数值,如:path、component、meta
        accessedRouters.children = routers.map((item) => ({
          path: item.path,
          component: () => import(`@/views/${item.component}`),
          meta: { title: item.title },
        }));
    
        // console.log(444, accessedRouters.children);
    
        // 8、最终提交给 mutations 进行修改
        commit("SET_ROUTERS", accessedRouters);
        return accessedRouters;
      },
    };
    
    export default {
      namespaced: true,
      state,
      mutations,
      actions,
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43

    请添加图片描述

    4、执行动态添加路由,修改 src/permission.js 代码

    import router from "@/router";
    import { getToken } from "@/utils/auth";
    import store from "./store";
    import { Message } from "element-ui";
    
    router.beforeEach(async (to, from, next) => {
      document.title = `${to.meta.title} - 长乐未央`;
    
      const hasToken = getToken();
      if (hasToken) {
        if (to.path === "/sign_in") {
          next({ path: "/" });
        } else {
          try {
            const hasRouters =
              store.getters.routers && store.getters.routers.length > 0;
            if (hasRouters) {
              next();
            } else {
              const { routers } = await store.dispatch("auth/getInfo");
              // 9、给请求结果赋值为 accessRoutes
              const accessRoutes = await store.dispatch(
                "permission/generateRouters",
                routers
              );
    
              // 10、调用 router 实例里面的 addRoute 方法动态增加路由
              router.addRoute(accessRoutes);
    
              // 11、如有错误,跳转到401页面
              router.addRoute({ path: "*", redirect: "/401" });
              // 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) {
            await store.dispatch("auth/resetToken");
            Message.error(error || "Has Error");
            next("/sign_in");
          }
        }
      } else {
        if (to.path === "/sign_in") {
          next();
        } else {
          next("/sign_in");
        }
      }
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49

    5、修改 src/router/index.js 路由列表

    import Vue from "vue";
    import VueRouter from "vue-router";
    import Layout from "@/views/layout/IndexView";
    
    Vue.use(VueRouter);
    
    const routes = [
      {
        path: "/sign_in",
        component: () => import("@/views/auth/SignIn"),
        meta: { title: "登录" },
      },
      {
        path: "/401", // 无权限访问
        component: () => import("@/views/error-page/Page401View"),
        meta: { title: "401" },
      },
      {
        path: "/",
        component: Layout,
        children: [
          {
            path: "",
            component: () => import("@/views/HomeView"),
            meta: { title: "首页" },
          },
        ],
      },
    ];
    
    const router = new VueRouter({
      mode: "history",
      base: process.env.BASE_URL,
      routes,
    });
    
    export default router;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    测试

    此时页面都可以正常访问,功能也都是好的

    左侧菜单栏

    修改 views/layout/components/SideBar.vue

    <template>
      <el-aside width="200px">
        <el-col>
          <el-menu
            :router="true"
            :default-active="activeMenu"
            class="el-menu-vertical-demo"
          >
            <el-menu-item index="/">
              <i class="el-icon-pie-chart">i>
              <span slot="title">仪表盘span>
            el-menu-item>
    
            <el-submenu :index="menu.title" v-for="menu in menus" :key="menu.id">
              <template slot="title">
                <i :class="menu.icon">i>
                <span>{{ menu.title }}span>
              template>
              <el-menu-item
                :index="child.path"
                v-for="child in menu.children"
                :key="child.id"
                >{{ child.title }}el-menu-item
              >
            el-submenu>
          el-menu>
        el-col>
      el-aside>
    template>
    
    <script>
    // 1、导入辅助函数 mapGetters
    import { mapGetters } from "vuex";
    
    export default {
      // 3、打印所有菜单
      // created() {
      // console.log(this.menus);
      // },
      computed: {
        // 2、把 menus 这个 Getters 映射过来,在模板中循环
        ...mapGetters(["menus"]),
        // 4、动态选中当前路由
        activeMenu() {
          // console.log(this.$route.path); // 获取当前路径
          return this.$route.path;
        },
      },
    };
    script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
  • 相关阅读:
    Asp .NetCore 微信订阅号自动回复之文本篇
    HTTP与HTTPS
    记录在搭建Jenkins时,所遇到的坑,以及解决方案
    读高性能MySQL(第4版)笔记08_创建高性能索引(上)
    第6章 - 多无人车系统的协同控制 --> 无人车运动原理
    【OpenGL】笔记八、摄像机(View矩阵)
    NI Package Manager创建程序包
    Android OpenGL ES 3.0 FBO 离屏渲染
    python调用SDK的问题
    「一体化信息建设」,江苏人社如何完成数据安全管控(成果篇)
  • 原文地址:https://blog.csdn.net/huangdj321/article/details/125898518