Vue3+Vite+TypeScript+Element Plus开发-13.动态路由-动态删除路由

 系列文档目录

Vue3+Vite+TypeScript安装

Element Plus安装与配置

主页设计与router配置

静态菜单设计

Pinia引入

Header响应式菜单缩展

Mockjs引用与Axios封装

登录设计

登录成功跳转主页

多用户动态加载菜单

Pinia持久化

动态路由 -动态增加路由

动态路由-动态删除路由 

路由守卫-无路由跳转404 

路由守卫-未登录跳转登录界面

 登录退出

Tags-组件构建

Tags-与菜单联动 

Pinia持久化优化

按钮权限

客制按钮组件

客制Table组件

客制Form组件

国际化

配置文件


文章目录

目录

 系列文档目录

文章目录

前言 

删除路由

1.路由变化状况

2.官方说明文档

3.动态删除路由     

 4.演示效果

后续 

参考文献 


前言 

       在前一章节中,主要探讨了如何动态增加路由配置。在实际使用过程中,发现了一个问题:当用户切换账号时,之前账号的路由仍然保留在路由表中。这导致即使菜单中没有对应的路由,用户也可以通过直接在地址栏输入网址来访问该页面,从而可能引发权限问题。为了避免这一问题,本章节将重点讲解如何动态移除路由,确保在用户切换账号时,旧账号的路由能够被正确清理,从而保障系统的安全性和权限管理的准确性。


删除路由

1.路由变化状况

        使用  admin  账号登录后,再切换至  user  账号登录时,发现路由(Router)未发生变化。原因是之前登录账号的动态路由仍然保留在路由表中,因此需要将其删除。

2.官方说明文档

  有几个不同的方法来删除现有的路由:

  • 通过添加一个名称冲突的路由。如果添加与现有途径名称相同的途径,会先删除路由,再添加路由:

     
    router.addRoute({ path: '/about', name: 'about', component: About })
    // 这将会删除之前已经添加的路由,因为他们具有相同的名字且名字必须是唯一的
    router.addRoute({ path: '/other', name: 'about', component: Other })
  • 通过调用 router.addRoute() 返回的回调:

     
    const removeRoute = router.addRoute(routeRecord)
    removeRoute() // 删除路由如果存在的话

    当路由没有名称时,这很有用。

  • 通过使用 router.removeRoute() 按名称删除路由:

     
    router.addRoute({ path: '/about', name: 'about', component: About })
    // 删除路由
    router.removeRoute('about')

    需要注意的是,如果你想使用这个功能,但又想避免名字的冲突,可以在路由中使用 Symbol 作为名字。

当路由被删除时,所有的别名和子路由也会被同时删除

3.动态删除路由     

        在使用  addRouter  函数动态增加路由之前,先通过  router.removeRoute  方法动态移除已存在的路由。在执行动态移除路由操作时,需要注意排除一些不需要移除的路由项。

在本案例中,通过调用  router.removeRoute()  方法按路由名称进行删除操作,以下是关键代码示例:

// 增加删除路由
  routerList.forEach((item:any) => {
    
    if (item.name === 'main' 
        || item.name === 'home' 
        || item.name === '404' 
        || item.name === 'login'
        || item.name === 'error'
        || item.name === 'undefined'
        || item.path === '/'
        || item.path === '/main') 
      return
    router.removeRoute(item.name)
  });

 以下是优化后的  src/stores/index.ts  完整代码示例:

// src/stores/index.ts

import { defineStore } from 'pinia';
import router from '../router';
import type { Component } from 'vue';

 
 

type Modules = Record<string, () => Promise<{ default: Component }>>;
 

// 定义公共 store
export const useAllDataStore = defineStore('useAllData', {
  // 定义状态
  state: () => ({
    isCollapse: false, // 定义初始状态
    username: '',
    token_key: '',
    menuData:[],
  }),

  // 定义 actions
  actions: {
    // 设置用户名
    setUsername(username: string) {
      this.username = username;
    },

    // 获取用户名
    getUsername(): string {
      return this.username;
    },

    // 设置 token_key
    setTokenKey(token_key: string) {
      this.token_key = token_key;
    },

    // 获取 token_key
    getTokenKey(): string {
      return this.token_key;
    },
    // 设置菜单数据
    setMenuData(menuData: any){
      addRouter(menuData)
      this.menuData = menuData
    },
    // 获取菜单数据
    getMenuData(): [] {
      return this.menuData;
    },
  },
  persist: {
    enabled: true,
    strategies: [
      {
        key: 'useAllData-store',
        storage: localStorage,
        paths: ['token_key','menuData'], // 指定需要持久化的字段
      },
    ],
  },


});

function addRouter(menuData: any){
  const routerList=router.getRoutes()
  const modules: Modules = import.meta.glob('../views/**/*.vue') as Modules;
  const routerArr=[]

  menuData.forEach((item:any) => {
   // console.log(item) 
    if(item.children){
     item.children.forEach((child:any) => {
       
       const componentPath = `../${child.path}.vue`;
       
       const module = modules[componentPath];
  
       if (module) {
         /*
         module().then(({ default: component }) => {
           child.component = component;
         });
         */
         child.component = module;
         routerArr.push(child)
          
       }
     });
   }
   else
   {
     const componentPath = `../${item.path}.vue`;
     const module = modules[componentPath];
     if(module)
     {
       item.component = module;
       routerArr.push(item)
     }

   }
  });
  // 增加删除路由
  routerList.forEach((item:any) => {
    
    if (item.name === 'main' 
        || item.name === 'home' 
        || item.name === '404' 
        || item.name === 'login'
        || item.name === 'error'
        || item.name === 'undefined'
        || item.path === '/'
        || item.path === '/main') 
      return
    router.removeRoute(item.name)
  });
  
  routerArr.forEach((item:any) => {
 
   router.addRoute('main',
     {
     path: item.index,
     name: item.label,
     component: item.component,
     
   });
 
})
const routerListLast=router.getRoutes()
console.log(routerListLast)

}

export function ReloadData() {
  const store = useAllDataStore();
  const menuData = store.getMenuData();
  addRouter(menuData);

 

}

 4.演示效果

使用  admin  账号登录时,系统应根据  admin  角色的权限动态加载对应的路由,满足预期。

 使用  user账号登录时,系统应根据  user角色的权限动态加载对应的路由,满足预期。


后续 

 下一章节重点讨论路由守卫


参考文献 

 动态路由 | Vue RouterVue.js 的官方路由https://router.vuejs.org/zh/guide/advanced/dynamic-routing.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值