Skip to content

路由白名单

stores/login.ts

ts
import { defineStore } from "pinia";

import { ref } from "vue";

interface UserInfo {
  name: string;
  avatar: string;
}

export const useLoginStore = defineStore("login", () => {
  const token = ref("");

  const hasUserInfo = ref<UserInfo>({
    name: "管理员",
    avatar: "https://jsopy.oss-cn-beijing.aliyuncs.com/IMAGES/avatar.jpg",
  });

  function getUserInfo() {
    return hasUserInfo.value;
  }

  function setToken(newToken: string) {
    token.value = newToken;
  }

  function setUserInfo(newUserInfo: UserInfo) {
    hasUserInfo.value = newUserInfo;
  }

  return { token, hasUserInfo, getUserInfo, setToken, setUserInfo };
});

config/permission.ts

ts
import router from "@/router";
import { useLoginStore } from "@/stores/login";

// 白名单
const whiteList = ["/login"];
/**
 * 路由前置守卫
 */
router.beforeEach(async (to, from, next) => {
  // 存在 token ,进入主页
  // if (store.state.user.token) {
  // 快捷访问
  if (useLoginStore().token) {
    if (to.path === "/login") {
      next("/admin");
    } else {
      // 判断用户资料是否获取
      // 若不存在用户信息,则需要获取用户信息

      if (!useLoginStore().hasUserInfo) {
        // 触发获取用户信息的 action,并获取用户当前权限
        // const { permission } = await store.dispatch('user/getUserInfo');
        // 这就是获取用户信息
        await useLoginStore().getUserInfo();
        // // 处理用户权限,筛选出需要添加的权限
        // const filterRoutes = await store.dispatch('permission/filterRoutes', permission.menus);
        // console.log(filterRoutes);
        // // 利用 addRoute 循环添加
        // filterRoutes.forEach(item => {
        //     router.addRoute(item);
        // });
        // 添加完动态路由之后,需要在进行一次主动跳转
        return next(to.path);
      }
      next();
    }
  } else {
    // 没有token的情况下,可以进入白名单
    if (whiteList.includes(to.path)) {
      next();
    } else {
      next("/login");
    }
  }
});

备注

获取用户信息放在了 permission.js 文件中,因为获取用户信息后,需要根据用户权限动态添加路由,所以放在了 permission.js 文件中

在 main.js 中引入permission.js

js
import ElementPlus from "element-plus";

import { createPinia } from "pinia";

import { createApp } from "vue";

// 引入 时间戳
import installFilter from "@/utils/globalzhiling.js";

import App from "./App.vue";

import router from "./router";

import "@/config/permission.js";

import "virtual:uno.css";

import "normalize.css";

import "element-plus/dist/index.css";

const app = createApp(App);

// 绑定自定是指令
installFilter(app);

app.use(createPinia());
app.use(router);
app.use(ElementPlus);
app.mount("#app");