Vue3+Vite实现动态路由

news2025/2/27 20:48:30

项目基本目录


1.首先定义初始默认的路由routes(router.js文件),vue文件使用import引入可以按需加载

import {
    createRouter,
    createWebHashHistory
} from "vue-router";

import store from '../store/index.js'

const routes = [{
        path: "/login",
        component: () => import("../view/Login/index.vue"),

        children: [],
        meta: {
            title: '登录页',
            hideMenu: true, //加入hideMenu属性,不展示在侧边栏
        },
        name: "Login",
    },
    {
        path: "/",
        component: () => import("../view/Home/index.vue"),
        meta: {
            keepalive: true,
            title: "主页",
        },
        name: 'Home',
        // hideMenu: true,//不展示在侧边栏
        children: [],
        redirect: '/index'
    },
]

2.在store的login.js模块写入调用后端数据的函数(写在vuex的action对象中,方便全局异步调用)

Vuex 允许我们将 store 分割成模块(module),比如登录模块,项目各个业务不相关的模块。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块(具体可以看主页另一篇博客)

3.执行addRoutes函数获取动态路由 (在router.js文件,点击登录成功后,在全局路由守卫去判断是否登录成功,再调用addRoutes函数) 

(1)全局路由守卫逻辑具体可看注释,好处是进入项目之后,刷新页面路由守卫会拦截跳转,可以重新执行addRoutes()获取路由,先获取动态路由,再执行跳转,不然页面会报本地路由找不到(一个小坑)

(代码如下)

router.beforeEach(async (to, from, next) => { //路由守卫
    if (store.state.login.token) { //存在token
        if (to.path == '/login') { //存在token,如果想跳转到登录页,默认有token跳转进项目首页
            next({
                path: '/'
            })
        } else { 
                //如果存在token,跳转进项目页面,则判断当前后端返回的路由有无长度
                //或者有无即将跳转路由的name
            if (store.getters['login/getRoutes'].length || to.name != null) {
                next() //有的话直接跳转
            } else { //不满足条件的话,重新请求后端动态路由数据
                await addRoutes(); //addRoutes()必须加入await!!!!等待逻辑执行完毕获取路由
                // 如果 addRoute 未完成,路由守卫会一层一层的执行执行,不加next()可能导致卡死!
                //直到 addRoute 完成,找到对应的路由
                next({
                    ...to,
                    replace: true
                })
            }
        }
    } else {
        if (to.path == '/login') {
            next()
        } else {
            next('/login')
        }
    }
})

后端返回的格式

(2)(重点在这,前面的步骤都可以不是重点)Vite使用import.meta.glob动态导入view文件夹所有前端页面,并调用addRoutes()函数执行获取动态路由数据并做处理(代码如下),主要作用是替换掉后端返回的component格式,再addRoute进路由表(看不懂的可以看代码注释或者可以搬进自己的项目打印看看每一步获取的数据)

let asyncRoutes = [] //定义数组接收后端返回的路由

const routeAllPathToCompMap =import.meta.glob(`../view/**/*.vue`);
//**为通配符,vite不支持require导入方式,故用import.meta.glob(vite动态导入)
/*import.meta.glob
 * 该方法匹配到的文件默认是懒加载,通过动态导入实现,构建时会分离独立的 chunk,是异步导入,返回的是 Promise
 * /*import.meta.globEager
 * 该方法是直接导入所有模块,并且是同步导入,返回结果直接通过 for...in循环就可以操作
 */
async function addRoutes() {
    await store.dispatch('login/getNewRoutes').then((res) => { //获取后端返回的动态路由
        if (res.data && res.data.length) {
            // let homeRouteChildren = [];
            asyncRoutes = res.data;
            /*
             * 1。拿到处理完毕home的children,最终替换掉原来的children,给菜单渲染提供支持
             * 2.通过递归,调用router.addRoute,把每一项route插到对应的父route下
             */
            //服务端配置了路由,但前端还没添加对应文件的路由列表,内容是路由的component值(服务端的)
            // const unForList = ['']
            const homeChildren = routes[1].children;
            const dfs = (parentRouteName = 'Home', asyncRoutes = [], originRouteChildren = []) => {
                if (!Array.isArray(asyncRoutes)) return [];
                asyncRoutes.forEach(route => {
                    // if (unForList.includes(route.component)) return;
/**后端返回来的路由component是字符串,如component: "view/Index/index.vue",
 * 前端需要把component: "view/Index/index.vue" 转化为组件对象
 * component:() => import("/src/view/Index/index.vue")
**/
                    route.component = routeAllPathToCompMap[`../${route.component}`];
                    // route.component = () => import(`../${route.component}`);
                    const routeChildren = route.children;

                    router.addRoute(parentRouteName, route);

                    route.children = dfs(route.name, routeChildren)

                    originRouteChildren.push(route)
                })
                return originRouteChildren
            }
            // homeRouteChildren = dfs(asyncRoutes)
            dfs('Home', asyncRoutes, homeChildren)
        }
    });
}

 最终转化完成,路由数据格式如下 

动态路由到此完成

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/407712.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

jsjiami.com V6版本,js解密的方法。

我们在爬内容,抓取页面的时候,总会遇到sojson v5,jsjiami.com的v6加密。 jsjiami v6 : JS加密,JS不可逆加密,JS混淆,JS混淆加密,JS压缩加密 - [JavaScript加密] 我看了下这个js完全有效。废话不多说。直接上代码。 (function (…

vue中深度选择器

scoped的作用 scoped 可以使当前的样式只在自己当前的组件内起作用。为了防止在一个组件内引入了子组件,而子组件没有加scoped。这个时候如果父子组件有相同的类名,就会产生样式的影响。 原理: 加了scoped就相当于给当前组件所有的标签添加一个【data-v-…

微信小程序实现轮播图

实现轮播图之前必须知道以下三点: 一、轮播图外层容器swiper 二、每一个轮播项swiper-item 三、swiper标签存在默认样式 1. width 100% 2. height 默认为 150px 3 .swiper高度无法实现由内容撑开 默认的150px高度的轮播图如下图: 原图是长这个样子的&#xf…

bootstrap-fileinput(二:编辑(修改)界面文件的上传,回显,删除(数据库同时删除)的操作 )

文章目录bootstrap-fileinput(二:编辑(修改)界面文件的上传,回显,删除(数据库同时删除)的操作 )一、编辑界面文件的上传二、编辑界面文件的回显1.文件的实体类:2.想要回显文件,首先要在工程类(你的编辑界面的主类)里面…

ES6面试问题汇总

面试官通过总问题,ES6方法开始提问 1.ES6有哪些新增方法?/你了解哪些ES6方法?(总问题) 块级作用域、 模板字符串、 解构赋值、 箭头函数、 函数默认参数、 剩余参数&运算符、 set和map、 import和exprot用…

Vue中实现过渡动画

文章目录Vue的transition动画Transition动画的使用Transition组件的原理Transition动画的classVue的animation动画Animation动画的使用同时设置两种动画(了解)过渡的模式mode列表过渡列表过渡的介绍列表过渡的使用Vue的transition动画 Transition动画的使用 在开发中&#xf…

vite配置cdn优化打包体积

文章目录前言一、版本确认二、使用步骤1.rollup-plugin-visualizer打包体积可视化面板2.配置cdn方法第一种方法: vite-plugin-cdn-import第二种方法: rollup-plugin-external-globals总结前言 大家都知道前端性能优化的方法,cdn外部引入的方…

【微信小程序】小程序知识补充篇

🎁写在前面: 观众老爷们好呀,这里是前端小刘不怕牛牛频道,小程序系列又更新了呀。 还有就是中秋节就快来啦,程序员过中秋,当然是要好好放松一下啦,那么中秋前我们就不能偷懒了,赶紧学…

Controller层接收前端传参的几种方法。@RequestParam、@RequestBody、@PathVariable。及参数校验。

一、RequestParam 主要用于将请求参数区域的数据映射到控制层方法的参数上 // http://localhost:8080/wh/user/edit?Id9452659856325148452&name天天向上// RequestParam源码Target({ElementType.PARAMETER}) // 只能作用于参数上 Retention(RetentionPolicy.RUNTIME) D…

vue watch监听数据解决新旧值一样的问题(newValue, oldValue)

watch是监听 Vue 实例变化的一个表达式或方法。回调函数得到的参数为新值和旧值。 基础用法 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge…

异步函数async

什么是同步异步 在最新的ES7&#xff08;ES2017&#xff09;中提出的前端异步特性&#xff1a;async、await。 在了解async和await之前得先明白什么是同步函数&#xff0c;什么是异步函数。 同步函数&#xff1a;当一个函数是同步执行时&#xff0c;那么当该函数被调用时不会…

前端CryptoJS和Java后端数据互相加解密(AES)

目录一、序言二、关于前端CryptoJS1、CryptoJS简单介绍2、加密和填充模式选择3、前端AES加解密示例(1) cryptoutils工具类(2) 测试用例(3) 加解密后输出内容说明三、Java后端AES加解密1、Java中支持的加密模式和填充说明2、工具类CryptoUtils3、测试用例一、序言 最近刚好在做…

nodejs——解决跨域问题

目录 1什么是跨域 2解决 1 jsonp(缺点&#xff1a;不能请求post请求&#xff09; 1 index.html页 2 proxy.js页面 搭建一个服务器&#xff08;写好代码后&#xff0c;在cmd上启动&#xff09; 3效果 2服务端代理 &#xff08;由于后端请求不受浏览器同源策略影响&…

Bootstrap、栅格系统布局

一、Bootstrap Bootstrap是一个基于HTML、CSS和JavaScript语言编写的框架&#xff0c;具有简单、灵活的特性&#xff0c;拥有样式库、组件和插件。 Bootstrap常用来开发响应式布局和移动设备优先的Web项目&#xff0c;能够帮助开发者快速搭建前端页面。Bootstrap官方网站:Boot…

VUE3构建Cesium项目

目录 1.Cesium开发参考资料 2.VUE中使用Cesium 2.1 使用VUE创建项目 1.创建test项目 2.项目中引入Cesium 3.修改App.vue如下 4.将cesium静态文件复制至public下 5.运行效果 1.Cesium开发参考资料 Cesium官方网站&#xff1a;Cesium: The Platform for 3D Geospatial …

前端接收 type: “application/octet-stream“ 格式的数据并下载,解决后端返回不唯一

前端接收 type: “application/octet-stream“ 格式的数据并下载&#xff0c;还有后端既返回octet-stream还返回JSON数据时的处理方法 今天些项目的时候&#xff0c;后端改了一下文件下载的方式&#xff0c;打算用接口返回 type: “application/octet-stream“格式的数据&…

【微信小程序】全局配置

目录 全局配置文件及常用的配置项 全局配置 - window 1. 小程序窗口的组成部分 2. 了解 window 节点常用的配置项 3. 设置导航栏的标题 4. 设置导航栏的背景色 5. 设置导航栏的标题颜色 6. 全局开启下拉刷新功能 7. 设置下拉刷新时窗口的背景色 8. 设置下拉刷新时 lo…

echarts 柱状图滚动

实现效果&#xff1a;柱形图展示水平滚动条&#xff0c;并且鼠标滚动支持让滚动条平移 echarts文档里&#xff0c;图形的滚动条分两种 内置型 &#xff08;效果是&#xff1a; 鼠标在图中点击拖动平移&#xff0c;在图中滚动缩放&#xff09;滚动条型 &#xff08;效果是&…

高德地图自定义图标的点标记Marker--初体验(二)

点标记Marker创建一个默认图标的点标记:创建一个自定义图标的点标记:new AMap.Marker({}) 参数说明本文以Marker为主&#xff0c;其他点标记方法大差不差 通过上两篇文章我们已经了解到如何引入高德地图并进行初始化了&#xff0c;本文主要讲解普通点标记Marker,Marker 类型推荐…

框架获取当前登录用户以及用户信息

CSDN话题挑战赛第2期 参赛话题&#xff1a;学习笔记 前言 &#x1f4eb; 作者简介&#xff1a;「六月暴雪飞梨花」&#xff0c;专注于研究Java&#xff0c;就职于科技型公司后端中级工程师 &#x1f525; 三连支持&#xff1a;如果此文还不错的话&#xff0c;还请 ❤️关注、&…