实践记录笔记二 | 青训营

75 阅读2分钟

不同用户不同访问权限

在我搭建的后台管理系统小项目中,需要实现一个根据不同用户身份提供不同访问权限的功能:

导航栏显示不同内容

  1. 实现的基本逻辑

    • 用户登录账号,根据后端返回的用户和管理员身份区分码,确定身份

      在这个项目中的逻辑是后端直接返回应该显示的导航栏数据,我认为不对,这部分数据应该是由前端来写的

    • 将身份对应的导航栏内容存入store和Cookie中

      存入Cookie中是因为store.state的数据会因为浏览器刷新而重新初始化,所以要存入缓存,后面会详细说明

    • 在导航栏组件中读取导航栏内容

  2. 实操

    • 编写store中用于缓存导航栏数据的mutations

      //store/tab.js
      import Cookie from 'js-cookie'
      export default {
          state: {
              menu: []
          },
          mutations: {
              //不同用户的不同menu
              setMenu(state, menu) {
                  state.menu = menu;
                  //将菜单存入浏览器缓存中,防止每次刷新后数据丢失
                  //注意要将数据转化为字符串
                  Cookie.set('menu', JSON.stringify(menu))
              }
          }
      }
      
      //store/index.js
      import Vue from 'vue'
      import Vuex from 'vuex'
      
      import tab from './tab'
      
      Vue.use(Vuex)
      
      export default new Vuex.Store({
          //模块化管理
          modules: {
              tab
          }
      })
      
    • 用户登录,并存入到导航栏数据

      注意此处的导航栏数据是由后端返回

      //Login.vue
      import { login } from "../api/index"
      import Cookie from "js-cookie"
      
      export default {
        ...
        methods: {
          //登录请求
          handleLogin() {
            //发送登录请求
            login(this.form).then(({data}) => {
             ... //登录成功后
                    //将不同身份对应的不同菜单栏项存入store.tab中
                    this.$store.commit('setMenu', data.menu);
                    //跳转到页面
                    this.$router.push({ name: "home" });
            ... //后续其他处理
            })
          },
        },
      };
      

      其中,data数据段

      image-20230420101905-t5mtdht.png

    • 在导航栏组件中获取导航栏数据

      //src/components/CommonAside.vue
      export default {
         ...
        computated: {
            //不同用户不同导航栏呈现
            menuData(){
              //判断当前数据是否在缓存中
              //先在缓存中找,缓存中有说明已经登录过;
              //缓存中没有,说明是初次登录,菜单栏存在state中
              //注意要将字符串转回js对象数组
              return JSON.parse(Cookie.get('menu')) || this.$store.state.tab.menu
          }
        }
      }
      
  3. 分析

    为什么需要将数据存在Cookie缓存?

    • store中的state是保存在内存中的,只要浏览器页面不被关闭,它们的值就会一直存在

    • 刷新浏览器页面,store中的state数据将会被初始化为初始值

      因为在刷新浏览器时,页面和所有已加载的JavaScript代码都会被重新加载,包括Vuex store实例

      因此,当store实例被重新创建时,其中的状态(state)也会被重新初始化为初始值

    • 为了避免在刷新浏览器后丢失store的state数据,可以使用一些技术来将其持久化存储

      如使用浏览器的本地存储(localStorage)或其他外部存储库

      这样可以确保在下一次加载页面或重新打开浏览器后,数据仍然存在并可以被恢复到之前的状态

限制部分路由的跳转

动态注册路由

  1. 问题描述

    • 不同的登录身份会呈现不同导航菜单,也只能跳转特定的页面

    • 也就是说对VueRouter()​​中route​​的配置(即路由表)不能是写死的,而是先验证身份,再动态配置的

      //src/routers/index.js
      import Vue from 'vue'
      import VueRouter from 'vue-router'
      
      export default new VueRouter({
         routes: [] //里面不能写死数据,不然什么身份都能通过修改路径进行页面跳转
      })
      
  2. 解决方案

    使用vue封装好的动态注册路由的接口,动态添加路由到路由表中

    const userMenu = [
            {
                path: "/home",
                name: "home",
                label: "首页",
                icon: "s-home",
                url: "Home/Home",
            },
            {
                path: "/user",
                name: "user",
                label: "用户管理",
                icon: "user",
                url: "UserManage/UserManage",
            },
    ];
    
    //动态添加路由表内容
    router.addRoutes(userMenu)
    

    需要注意页面刷新后vue实例会被重新初始化,可能会出现路由表被重置为初始值的情况

    所以需要在Vue实例被创建后,再重新调用方法来获取路由表

    //src/main.js
    ...
    new Vue({
      router,
      store,
      render: h => h(App),
      create(){
        router.addRoutes(userMenu)
      }
    }).$mount('#app')