vue3+动态路由

news2025/2/23 18:43:14

         动态路由,也就是不是写死的路由,根据自己的需求加载不同的页面;现在很多的后台管理项目就是根据用户角色的不同分配不同的功能菜单(页面);

        根据用户登录的角色返回可以访问的页面路由,前端将路由存储到 pinia 实现持久话存储,然后在路由前置守卫用 addRoute 动态添加路由,对页面进行渲染。

        通常的实现步骤:

  1. 前端调用登录接口获取用户ID(uid)         
  2. 前端用uid请求接口获取路由表(JSON)
  3. 对路由表进行数据格式话形成树形结构
  4. 树形结构 转 vue路由结构
  5. 路由结构 转  静态路由
  6. 树形结构 转  菜单组件

 下面是我练习一个demo,仅用于学习与记录;

服务端代码结构:

         服务端在本地localhost:3007,

 


 server.js

//导入express 模块
const express = require("express")
//创建 express 实例
const app = express()
//导入cors 中间件
const cors = require("cors")
app.use(cors())
//配置表单解析中间件
app.use(express.urlencoded({extended:false}))

const useRouter = require("./router/index.js")

app.use("/api",useRouter)
app.listen(3007,function (){
    console.log("api server running at http://127.0.0.1:3007")
})

 router/index.js

const express = require("express")
const router = express.Router()
const users = require("../mockDB/user.js")
const routers = require("../mockDB/router.js")


router.post("/routers", (req, res) => {
    const {uid} = req.body
    if (uid) {
        let authRouterInfo;
        authRouterInfo = [];
        const userInfo = users.find(user => user.id === JSON.parse(uid))
        console.log(users)
        userInfo.auth.map((rid) => {
                routers.map((router) => {
                    if (router.id === rid) {
                        authRouterInfo.push(router)
                    }
                })
        })
        res.send({
            status: 0,
            msg: "post 请求成功",
            data: authRouterInfo
        })

    } else {
        res.send(
            {
                status: 0,
                msg: "查询不到此uid !",
                data: null
            }
        )
        }
    }
)
    module.exports = router

mockDB/user.js

module.exports = [
    {
        id:1,
        name:"zhangsan",
        auth:[2,3,6,7]
    },
    {
        id:2,
        name:"lisi",
        auth:[2,3,5,6,7,8]
    },
    {
        id:3,
        name:"wangwu",
        auth:[2,3,4,5,6,7,8]
    },
    {
        id:4,
        name:"mazi",
        auth:[6,7,8]
    }
]

mockDB/router.js 

module.exports = [
    {
        id:2,
        pid:0,
        path:"/course",
        name:"Course",
        title:"课程管理"
    },
    {
        id:3,
        pid:2,
        path:"operate",
        name:"CourseOperate",
        title:"课程操作",
        link:"/course/operate"
    },
    {
        id:4,
        pid:3,
        path:"info_data",
        name:"CourseInfoData",
        title:"课程数据",
        link:"/course/operate/info_data"
    },
    {
        id:5,
        pid:2,
        path:"add",
        name:"CourseAdd",
        title:"课程添加",
        link:"/course/add"
    },
    {
        id:6,
        pid:0,
        path:"/student",
        name:"Student",
        title:"学生管理"
    },
    {
        id:7,
        pid:6,
        path:"operate",
        name:"StudentOperate",
        title:"学生操作",
        link:"/student/operate"
    },
    {
        id:7,
        pid:6,
        path:"add",
        name:"StudentAdd",
        title:"学生增加",
        link:"/student/add"
    }
]

 前端代码结构:

         前端调用 /api/routers 传入 uid 获取用户路由表

调用接口

import axios from "axios"
import qs from "qs"
export function getRouters(uid){
    return  axios({
        url:"http://127.0.0.1:3007/api/routers",
        method:"post",
        header:{
            "Content-type":"application/x-www-from-urlencoded"
        },
        data:qs.stringify({uid})
    })
}

 将路由表格式成树结构, 路由表结构mockDB/router.js

export function formatRouterTree(datas) {
    let res = []
    datas.map(data => {
        // data.children = []
        //console.log(data.children)
        if (data.pid === 0) {
            res.push(data)
        } else {
            add2Tree(data, res)
        }
    })
    return res

}

function add2Tree(data, res) {
    res.map(r => {
        if (data.pid === r.id) {
            if (!r.children) r.children = []
            r.children.push(data)
        } else {
            if (r.children)
                add2Tree(data, r.children)
        }
    })

}

树结构 转 vue路由结构

export function generateRouter(userRouters) {
    let newRouters;
    newRouters = userRouters.map(r => {
        let routes = {
            path: r.path,
            name: r.name,
            component: () => import(`../view/${r.name}.vue`)
        }
        if (r.children) {
            routes.children = generateRouter(r.children)
        }
        return routes
    });
    return newRouters
}

先配置静态的路由,接着添加动态路由  ==> router/route.js

const routes = [
    {
        path:"/",
        name:"Home",
        component:() => import ("../view/Home.vue")
    },
    // {
    //     path:"/404",
    //     name:"NotFound",
    //     component:() => import ("../view/NotFound.vue")
    // },
    // {
    //     path:"/:pathMatch(.*)",
    //     redirect:"/404"
    // }
]
export default routes;

router.beforeEach(async (to, from, next) => {
    const store = useRouterStore()
    if (!store.hasAuth) {
        await store.getRoutersList()
        let newRoutes = generateRouter(store.userRouters)
        let a = [...newRoutes,
            {
                path: "/404",
                name: "NotFound",
                component: () => import ("../view/NotFound.vue")
            },
            {
                path: "/:pathMatch(.*)",
                redirect: "/404"
            }]
        a.forEach((r) => {
            router.addRoute(r)
        })
        next({...to, replace: true})
        console.log(a)
    }else {
        if(to.name === null){
            next("/404")
        }
        next()
    }

})

递归组件模版渲染菜单组件

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

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

相关文章

JSON parse error: Cannot deserialize value of type `java.util.Date` from String

DateTimePicker DateTimeFormat("yyyy-MM-dd HH:mm:ss")日期格式转换异常 最近在学习,练习一个项目使用的日期格式是yyyy-MM-dd HH:mm:ss格式的,在后端Java与MySQL这边的转换中一开始格式没有统一间歇性的就会报异常,后面采用了一个DateTimeFormat("yyyy-MM-d…

vue组件的动态加载

​ 平常的vue项目开发,已经很难遇见一千行,甚至几千行代码的页面了,毕竟大家都会去拆分组件。但如果一个页面需要通过十几个组件或者几十个组件中的某几个组件去排列组合渲染,此时用动态加载就很有必要了。 ​ 我自己在开发过程中…

v-if与v-for为什么不建议一起使用?

1、作用 v-if指令用于条件性地渲染一块内容。这块内容只会在指令的表达式返回true值的时候被渲染。 v-for指令基于一个数组来渲染一个列表。v-for指令需要使用item in items 形式的特殊语法,其中items是源数据数组或者对象,而item则是被迭代的数组元素的…

JS-获取DOM元素的五种方法

介绍 本文主要介绍通过JS获取DOM元素的5种方法: 根据id名获取元素:getElementById;根据标签名获取元素:getElementsByTagName,返回一个数组;根据类名获取元素:getElementsByClassName,返回一个…

当后端给我返回了302状态码

本文首发于:https://github.com/bigo-frontend/blog/ 欢迎关注、转载。 前言 前段时间接手了一个项目,在代码中看到了这样的一段代码: if (isHTML(data) &&response.request.responseURL?.indexOf(CAS_PREFIX) > -1) {window.l…

cesium简介

文章目录1.什么是Cesium?2.Cesium能做什么?3.Cesium的依赖性4.Cesium学习参考Cesium实战系列文章总目录: 传送门1.什么是Cesium? Cesium是AGI公司计算机图形开发小组与2011年研发的三维地球和地图可视化开源JavaScript库&#xf…

【微信小程序 | 实战开发】实现ES6转ES5开关

个人名片: 🐼作者简介:一名大二在校生,喜欢编程🎋 🐻‍❄️个人主页🥇:小新爱学习. 🐼个人WeChat:hmmwx53 🕊️系列专栏:🖼️ 零基础学Java——小白入门必备重识C语言——复习回顾

Java开发框架选型对比:ruoyi与yudao框架

1、基础开发框架 1.1 什么是基础开发框架? 基础框架可以理解为建立一个项目所需的基础框架,这个基础框架为凝聚了之前开发项目的通用、共性的方法、工具、技术等组成的代码包。 现有我们公司有两类基础框架:(1)基于w…

vue2使用element UI中Descriptions组件的遍历问题

需求描述:展示信息时其中部门区域是未知数量的,需要通过遍历进行展示。如下图举例,其中地址和备注是一一对应关系,需遵循该样式。 问题描述:起初我在el-descriptions中直接使用v-for进行遍历地址和备注两个el-descript…

实现异步的8种方式

前言异步执行对于开发者来说并不陌生,在实际的开发过程中,很多场景多会使用到异步,相比同步执行,异步可以大大缩短请求链路耗时时间,比如:「发送短信、邮件、异步更新等」,这些都是典型的可以通…

Switch语句用法及案例

​ 一、Switch语句用法 switch是多分支语句,用于判断一个表达式的值,然后执行相应的语句。(可以实现多选一) switch语句执行思路:利用表达式的值,来判断执行哪个语句。(简单的来说就是利用我们…

Vue 3 安装及环境配置

Vue 3 安装及环境配置1、安装 Node.js2、配置默认安装目录和缓存日志目录3、配置环境变量4、配置淘宝镜像5、安装 vue 和脚手架6、安装vue-cli 3.x7、创建 vue 3 项目8、可能遇到的问题1、安装 Node.js Node.js 官网:https://nodejs.org/en/download 安装成功后在…

Vue项目实战——实现一个任务清单【基于 Vue3.x 全家桶(简易版)】

Vue3.x 项目实战(一) 内容参考链接Vue2.x全家桶Vue2.x 全家桶参考链接Vue2.x项目(一)Vue2.x 实现一个任务清单Vue2.x项目(二)Vue2.x 实现GitHub搜索案例Vue3.x项目(三)Vue3.x 实现一…

Vue项目部署(Nginx)

本文记录如何将做好的Vue项目部署到服务器上,需要准备: linux系统的服务器或者虚拟机Vue项目打包Nginx服务器的配置和部署1、linux系统准备 本次使用云主机作为部署主机。 2、Vue项目打包 切换到项目所在目录,使用 npm run build 命令完成项目…

深度学习——VGG16模型详解

1、网络结构 VGG16模型很好的适用于分类和定位任务,其名称来自牛津大学几何组(Visual Geometry Group)的缩写。 根据卷积核的大小核卷积层数,VGG共有6种配置,分别为A、A-LRN、B、C、D、E,其中D和E两种是最…

yolov5源码解析(9)--输出

本文章基于yolov5-6.2版本。主要讲解的是yolov5是怎么在最终的特征图上得出物体边框、置信度、物体分类的。 一。总体框架 首先贴出总体框架,直接就拿官方文档的图了,本文就是接着右侧的那三层输出开始讨论。 Backbone: New CSP-Darknet53Neck: SPPF, …

JavaWeb酒店管理系统

酒店管理系统 一、项目介绍 1、项目用到的技术栈 开发工具:idea语言:java、js、htmlajax数据库:MySQL服务器:Tomcat框架:mybatis、jQuery 2、项目实现功能 管理员和用户登录和退出功能以及用户注册功能&#xf…

【第二趴】uni-app开发工具(手把手带你安装HBuilderX、搭建第一个多端项目初体验)

文章目录写在前面HBuilderXHBuilderX 优势HBuilderX 安装uni-app 初体验写在最后写在前面 聚沙成塔——每天进步一点点,大家好我是几何心凉,不难发现越来越多的前端招聘JD中都加入了uni-app 这一项,它也已经成为前端开发者不可或缺的一项技能…

Eolink 治愈了后端开发者的痛

一、前后端的爱恨情仇 最近公司的一个前端同事和一个后端同事吵了一架,事情大概是这样的。后端说要联调接口,前端说你的数据尽量按我的要求来,后端不干,说你这个没用。前端就讲道理呀,传统的前后端分离返回的格式要尽…

【node进阶】深入浅出websocket即时通讯(二)-实现简易的群聊私聊

✅ 作者简介:一名普通本科大三的学生,致力于提高前端开发能力 ✨ 个人主页:前端小白在前进的主页 🔥 系列专栏 : node.js学习专栏 ⭐️ 个人社区 : 个人交流社区 🍀 学习格言: ☀️ 打不倒你的会使你更强&a…