vue动态路由简单记录

vue动态路由简单记录

原有路由文件 ./router.ts


import VueRouter from 'vue-router';

export const router = new VueRouter({
  mode: 'history',
  routes: [
    {
      path: '/',
      redirect: '/test**',
    },
    {
      path: '/login',
      component: (Lazy => ({ render: h => h(Lazy) }))(defineAsyncComponent(() => import('./login.vue'))),
    },

    {
      path: '/aa',
      component: (Lazy => ({ render: h => h(Lazy) }))(defineAsyncComponent(() => import('./aa.vue'))),
     
    },
    

       {
      path: '/bb',
      component: (Lazy => ({ render: h => h(Lazy) }))(defineAsyncComponent(() => import('./bb.vue'))),
     
    },
  
    { path: '*', redirect: '/' },
  ],
});

// 在使用的的地方调用
import {router} from './router';
new Vue({
  router,
  pinia,
  render: h => h(App),
}).$mount('#app');

使用动态路由,将文件分为3份,baseRouter.ts, dynamicRoute.ts, index.ts,新建router文件夹,创建以上3个文件。

baseRouter.ts 配置基础路由


const routes = [
  {
    path: '/',
    redirect: '/test**',
  },
  {
    path: '/login',
    component: (Lazy => ({ render: h => h(Lazy) }))(defineAsyncComponent(() => import('./login.vue'))),
  },
 
  {
    path: '*',
    name: '404',
    component: ErrorPage
  }
];
export default routes;

dynamicRoute.ts 动态路由逻辑。const modules = import.meta.glob('../views/**/*.vue') vite框架使用,不然在动态路由中直接引用组件打包后会导致动态组件页面不显示。import.meta.glob文档地址


const modules = import.meta.glob('../views/**/*.vue');
import { defineAsyncComponent } from '@vue/composition-api';
import routes from './baseRouter';

const RouterPlugin = function () {
 this.$router = null;
};
RouterPlugin.install = function (router, store) {
 this.$router = router;
 // store 如果需要使用store 可以传入
 // this.$store = store;
 this.$router.$dynamicRoute = {
   // 全局配置
   safe: this,
   // 动态路由,需要在登录之后调用
   formatRoutes: function (aMenu = []) {
     // 此处所有的 aMenu 只有子元素可以点击
     const getChild = list => {
       let childList = [];
       list.forEach(item => {
         if (item.children && item.children.length) {
           childList = childList.concat(getChild(item.children));
         } else {
           childList = childList.concat(item);
         }
       });
       return childList;
     };
     let childList = getChild(aMenu);
     let oRouter = [];
     childList.forEach(item => {
       oRouter.push({
         path: `${item.menuPath}`,
         component: (Lazy => ({ render: h => h(Lazy) }))(defineAsyncComponent(modules[`../router1/${item.url}.vue`])),
       });
     });

     let aRouter = {
       path: '/router1',
       name: 'router1Page',
       component: (Lazy => ({ render: h => h(Lazy) }))(
         defineAsyncComponent(modules['../router1/index.vue'])
       ),
       children: oRouter,
     };

     this.safe.$router.addRoute(aRouter);
     // 查看配置之后的所有路由
     console.log(this.safe.$router.getRoutes());
   },
 };
};
export default RouterPlugin;

index.ts 文件配置


import Vue from 'vue';
import VueRouter from 'vue-router';
import baseRoutes from './baseRouter';
import RouterPlugin from './dynamicRoute';

Vue.use(VueRouter);

const createRouter = () => {
  return new VueRouter({
    // scrollBehavior 处理移动位置
    scrollBehavior(to, from, savedPosition) {
      if (savedPosition) {
        return savedPosition;
      } else {
        return {
          x: 0,
          y: to.meta.savedPosition || 0,
        };
      }
    },
    routes: [...baseRoutes],
    mode: 'history', //
  });
};
let router = createRouter();
/**
resetRouter函数用于重置路由,每一次动态配置路由之前要先重置路由
**/
export function resetRouter() {
  const newRouter = createRouter();
  router.match = newRouter.match; // reset router
  // store 使用vuex 或者 pinia
  RouterPlugin.install(router, store);
}
/**
 * 以下是缓存处理,看情况使用
当用户刷新页面时,路由数据会丢失,如果已经登录,需要重新渲染路由。渲染的路由数据在登录时存在浏览器本地
**/
// if (sessionStorage.getItem('hasLogin')) {
//   let sessionMenus = localStorage.getItem('menus')
//   sessionMenus = sessionMenus ? JSON.parse(sessionMenus) : []
//   let sessionRoutes = localStorage.getItem('userRoutes')
//   RouterPlugin.install(router, store)
//   sessionRoutes = sessionRoutes ? JSON.parse(sessionRoutes) : []
//   router.$dynamicRoute.formatRoutes(sessionRoutes, true)
//   store.dispatch('setUserRoutes', sessionRoutes)
//   store.dispatch('setMenus', sessionMenus)
// }

// router.beforeEach((to, from, next) => {
//   let hasLogin = sessionStorage.getItem('hasLogin')
//   // console.log(to, from)
//   if (to.name === from.name) {
//     return
//   }
//   console.log(hasLogin)
//   if (to.name === 'Login') {
//     sessionStorage.clear()
//     localStorage.clear()
//     store.state.userRoutes = []
//     store.state.menus = []
//     next({ replace: true })
//     resetRouter()
//     return
//   }
//   if (!hasLogin) {
//     next({ path: '/login', replace: true })
//     return
//   }
//   next()

// })

/**
 * 解决element-ui点击同一个菜单报错
 * @type {VueRouter.push|*}
 */
const originalPush = VueRouter.prototype.push;
VueRouter.prototype.push = function push(location) {
  return originalPush.call(this, location).catch(err => err);
};
export default router;


// 在使用的的地方调用
import router from './router/index';
new Vue({
  router,
  pinia,
  render: h => h(App),
}).$mount('#app');

在登陆之后或者判断获取到用户信息之后重置路由


import { resetRouter } from './router/index';
import {cloneDeep} from 'lodash'
  // menuList 为获取的菜单数据(树结构数据)
  //重置路由
  resetRouter();
  this.$router.$dynamicRoute.formatRoutes(cloneDeep(menuList));

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值