vue3动态路由

基本的思路:

拿到路由数据
---------》
遍历路由数据通过router.addRoute一个个的添加,同时将路由数据缓存起来
-----------》
当页面刷新时,从缓存里拿出路由数据再重新添加,同时配合路由守卫来跳页面

当页面刷新后,即使你动态路由添加上去了,也能通过getRoutes拿到,但是刷新页面时的跳转会有问题,提示你该路由不存在之类的,这时要在路由守卫里通过router.push来跳转,这样就可以了(还是会提示错误但不影响使用)

第一次尝试做动态路由,如果有更好的方法实现,希望能评论告诉我!!!
在页面刷新后,即使添加路由成功后跳转也无效,这里卡了我一两天

路由页

import { createRouter, createWebHashHistory, RouteRecordRaw } from 'vue-router';
import layout from '@/views/layout/index.vue';

const routes: Array<RouteRecordRaw> = [
  {
    path: '/',
    redirect: '/home/index'
  },
  {
    path: '/home',
    name: 'home',
    component: layout,
    meta: { title: '首页' },
    redirect: '/home/homeIndex',
    children: [
      {
        path: 'index',
        name: 'homeIndex',
        component: () => import('../views/home/index.vue'),
        meta: { title: '首页' }
      }
    ]
  },
  {
    path: '/login',
    name: 'login',
    component: () => import('../views/login/index.vue'),
    meta: { title: '登录' }
  },
  {
    path: '/404',
    name: '404',
    component: () => import('../views/errorPage/404.vue'),
    meta: { title: '404' }
  }
];

const router = createRouter({
  history: createWebHashHistory(),
  routes
});

export default router;

路由守卫的js文件

import router from './index';

// 路由拦截
router.beforeEach((to, from, next) => {
  const token = sessionStorage.getItem('token');

  if (token) {
    // 是否有该路径
    if (to.matched.length > 0 || from.path !== '/') {
      next();
    } else {
      // 防止页面刷新
      if (from.path == '/' && to.matched.length <= 0) {
        next(to.path);
      } else {
        next('/404');
      }
    }
  } else {
    // 反正让你去登录页
    if (to.path == '/login') {
      next();
    } else {
      next('/login');
    }
  }
});

login页面, store用的是Pinia

import { basicStore } from '@/store/basicData/index';
import { useRouter } from 'vue-router';
import { getCurrentInstance } from 'vue'

const router = useRouter();
const store = basicStore();
 //const {proxy}:any = getCurrentInstance();//获取公共方法

//登录成功后
  sessionStorage.setItem('token', 'afjskafjksafjsk');
 store.AddDynamicRoute(); // 获取菜单
 router.push({ name: 'homeIndex' });

main.ts页面

import pinia from './store';
import './router/permission'; // 路由守卫

const app = createApp(App);

app
.use(store)
.use(router)
.use(pinia)
.mount('#app')

app.vue页面,防止页面刷新动态路由消失

<script setup lang="ts">
import { basicStore } from './store/basicData/index';
const store = basicStore();
if (sessionStorage.getItem('token')) {
  // 防止刷新页面后动态路由消失
  store.AddDynamicRoute();
}
</script>

动态路由添加封装好的ts文件

import router from './index';
import testall from './test'; // 测试页面路由

// 所有的前端页面路由放到这来,然后通过这拿去注册路由
const routerlist = [...testall];

// 将后端菜单数据与前端路由匹配
const dealWithRoute = (use: Array<any>, all: Array<any> = routerlist) => {
  const resul: Array<any> = [];
  all.forEach((aa) => {
    use.forEach((bb) => {
      // 这匹配值根据后台传的值来定
      if (bb.path == aa.name) {
        if (bb.childer && bb.childer > 0) {
          dealWithRoute(bb.childer, aa.childer);
        }
        resul.push(aa);
      }
    });
  });
  addDynamicRoute(resul);
};

// 添加动态路由,parent默认为home是首页最外层的路由name名
const addDynamicRoute = (useroute: Array<any>, parent = 'home') => {
  for (let i = 0; i < useroute.length; i++) {
    if (useroute[i].childer && useroute[i].childer.length > 0) {
      router.addRoute(parent, useroute[i]);
      // 递归添加动态路由
      addDynamicRoute(useroute[i].childer, useroute[i].name);
    } else {
      router.addRoute(parent, useroute[i]);
    }
  }
};

export default dealWithRoute;

下载Pinia store >> basicData >> index.ts文件

import { defineStore } from 'pinia';
import dealWithRoute from '@/router/allRouter';

state: () => {
    return {
      MenuList: [] as any[], // 菜单数据
    };
 },
actions:{
/* 获取菜单,添加动态路由 */
    AddDynamicRoute () {
      let nowmenulist: Array<Object> = [];
      if (this.MenuList?.length > 0) {
        nowmenulist = this.MenuList;
      } else {
        // 通过接口拿菜单数据
        nowmenulist = [
          {
            icon: 'Menu',
            name: '控制台',
            path: 'homeIndex'
          },
          {
            icon: 'Stopwatch',
            name: '移动端商城',
            path: 'aa'
          },
          {
            icon: 'Ticket',
            name: '少时诵诗书',
            path: 'bb',
            childer: [
              {
                icon: 'ShoppingCart',
                name: '的点点滴滴',
                path: 'bb/dd'
              }
            ]
          },
          {
            icon: 'Reading',
            name: '灌灌灌灌',
            path: 'cc'
          }
        ];
      }
      this.MenuList = nowmenulist;
      dealWithRoute(nowmenulist); // 将拿到的菜单去匹配生成动态路由
      return true
    },
 }

你可能感兴趣的:(vue.js,javascript,前端)