位置: IT常识 - 正文

Vite4 + Vue3 + vue-router4 动态路由

编辑:rootadmin
Vite4 + Vue3 + vue-router4 动态路由

推荐整理分享Vite4 + Vue3 + vue-router4 动态路由,希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:,内容如对您有帮助,希望把文章链接给更多的朋友!

动态路由,基本上每一个项目都能接触到这个东西,通俗一点就是我们的菜单是根据后端接口返回的数据进行动态生成的。表面上是对菜单的一个展现处理,其实内部就是对router的一个数据处理。当然你只对菜单做处理也是可以的,但是没有任何意义,熟悉router的小伙伴都知道,如果你的一个路由存在,即使没有这个菜单,我只要改变浏览器的地址一样能访问到。所以你还是省不了修改router的步骤。通过接口获取数据的话就可以根据角色权限或者一些业务上的需求,根据不同属性实现路由的划分。达到不同的页面渲染效果。

本文只是讲解菜单的权限控制,不到按钮级别。其实按钮也是差不多的。可以设置一个属性表示菜单,一个属性表示按钮,每一个菜单的叶子节点上都包含根据权限返回的按钮数组。接着可以通过组件的形式去输出相应的按钮就可以。

一、搭建项目 😛😛😛

这里我已经提前搭建好了 Vite4+Pinia2+vue-router4+ElmentPlus搭建Vue3项目(组件、图标等按需引入)

二、根据上面链接搭建好项目,修改src/router/index.ts 😁 😉Vite4 + Vue3 + vue-router4 动态路由

asyncRoutes里面可以存放默认的一些路由,比如登录、404、403这些。由于我只是演示,所以就啥都不放了。清晰明朗一点。

import { createRouter, createWebHashHistory, RouteRecordRaw } from 'vue-router'export const asyncRoutes: RouteRecordRaw[] = []const router = createRouter({ history: createWebHashHistory(), routes: asyncRoutes, scrollBehavior: () => ({ left: 0, top: 0 })})export default router三、创建 'src/layout/index.vue' 文件 😁 😉

这个文件就是整个项目的布局,一般我们常见的项目都分为上下结构,就如下图。导航和菜单部分基本上是用户登录以后就已经确定好了,点击菜单的时候去切换路由。我这里由于这部分不是重点,所以我就很潦草的画了一个很简单的页面。

<template> <div style="padding: 100px;"> <div> <div v-for="(item, index) in menus[0].children" :key="index" style="margin-bottom: 20px;"> <router-link :to="item.path">{{item.title}}</router-link> </div> </div> <div> <router-view #default="{route, Component}"> <transition leave-from-class="ts-web-fade--leave-to" enter-active-class="animate__animated animate__bounceInRight"> <component :is="Component"></component> </transition> </router-view> </div> </div></template><script lang="ts">import appStore from '@/pinia';export default defineComponent({ setup() { const { menus } = appStore.permissionModule console.log(menus, 'menus') return { menus, } }})</script>四、创建 'src/pinia/modules/permission.ts' 文件 😁 😉

由于我这里是一个demo,没有真正的去接入后端。所以我暂时放入的静态数据。自己替换成接口返回就好。

import { defineStore } from 'pinia';import router from '@/router'// 这是整个项目的布局页面。根据自己的项目替换就好import Layout from "@/layout/index.vue";import {RouteRecordRaw} from "vue-router";export type MenuType = { path: string, title: string, component: string, redirect?: string, children?: Array<MenuType>}type RouterType = RouteRecordRaw & { hidden?: boolean; alwaysShow?: boolean;}export interface IPermissionState { routes: RouterType[] dynamicRoutes: RouterType[] menus: Array<MenuType>}function hasPermission<T>(roles: T[], route: RouterType) { if (route.meta && route.meta.roles) { return roles.some((role) => (route.meta?.roles as T[]).includes(role)); } return true}const modules = import.meta.glob('../../views/**/*.vue')const _import = (path: string) => () => import(`../../views/${path}.vue`)const assembleRouter = (routers: any) => { const addRouter = routers.filter((router: any) => { (router.title && router.icon) && (router.meta = { title: router.title, // icon: router.icon, // alwaysShow: router.alwaysShow || false, // affix: router.affix || false, }) if (router.component === 'Layout') { router.component = shallowRef(Layout) } else { if (import.meta.env.MODE === 'development') { router.component = _import(router.component) } else { router.component = modules[`../../views/${router.component}.vue`] } } if (router.children && router.children.length) { router.children = assembleRouter(router.children) } return true }) return addRouter}export function filterAsyncRoutes(routes: RouterType[], roles: string[]) { const res: RouterType[] = [] routes.forEach((route) => { const tmp = { ...route } if (hasPermission<string>(roles, tmp)) { if (tmp.children) { tmp.children = filterAsyncRoutes(tmp.children, roles) } res.push(tmp) } }) return res}export const permissionModule = defineStore({ id: 'permission', state(): IPermissionState{ return { routes: [], dynamicRoutes: [], menus: [] } }, actions:{ async getMenus() { try { // 这里由于不方便演示,所以我写的静态数据。换着自己对于的接口就好 const list:MenuType[] = [ { path: '/', title: 'ts-super-web', component: 'Layout', redirect: '/home', children: [ { title: 'home', path: 'home', component: 'home' }, { title: 'home1', path: 'home1', component: 'home1' } ] } ] this.menus = list // 组件路由 let addRouter = assembleRouter(this.menus) // addRouter = assembleRouterDelete(addRouter) // 动态添加菜单 addRouter.forEach((ts: any) => { router.addRoute(ts) }) } catch (err) { return Promise.reject(err); } } }})五、路由拦截器 😁 😉 😜

因为上面说到我没有真正的接入后端,所以这里我也没有进行token判断。自行增加一下就好,比较简单。除了token还可以在拦截器里面放置一个白名单列表,对于白名单里面的路由我们不做拦截。比如login登录页面、404等等。根据自己需求配置就好。

import router from '@/router'// @ts-ignoreimport NProgress from 'nprogress'import 'nprogress/nprogress.css'import appStore from "@/pinia";NProgress.configure({ easing: 'ease', // 动画方式 showSpinner: true, // 是否显示加载ico trickleSpeed: 200, // 自动递增间隔 minimum: 0.4, // 更改启动时使用的最小百分比})router.beforeEach(async (to, form, next) => { // 这里处理自己的逻辑,比如需要登录以后才能访问其他页面等等 NProgress.start() const { menus, getMenus } = appStore.permissionModule if (menus.length === 0) { try { // 调用接口获取菜单 进行跳转 await getMenus() next({ ...to, replace: true }) } catch (err) { next() } } else { next() } NProgress.done()})六、修改app.vue<template> <router-view /></template><style>html,body,#app { height: 100%; width: 100%; margin: 0; padding: 0;}</style>七、src/views下的两个home文件进行一下修改

home 这两个文件不修改也不影响。

<template> <p style="font-size: 32px;">你好,我是home</p></template>

home1 这两个文件不修改也不影响。

<template> <p style="font-size: 32px;">你好,我是home1</p></template>八、效果浏览

我是Etc.End。如果文章对你有所帮助,能否帮我点个免费的赞和收藏😍。

👇 👇 👇 👇 👇 👇 👇 👇 👇 👇 👇 👇
本文链接地址:https://www.jiuchutong.com/zhishi/298708.html 转载请保留说明!

上一篇:云化Web IDE,在线开发新模式(it云化)

下一篇:React基础-JSX语法列表渲染详解(react js 教程)

  • 荣耀X30i屏幕材质(荣耀x30i材质)

    荣耀X30i屏幕材质(荣耀x30i材质)

  • 美团单车在哪里付费(美团单车在哪里停车)

    美团单车在哪里付费(美团单车在哪里停车)

  • 荣耀x10max支持nfc功能吗(荣耀x10max支持广电卡吗)

    荣耀x10max支持nfc功能吗(荣耀x10max支持广电卡吗)

  • word文字替换怎么操作(word文字替换怎么弄出来)

    word文字替换怎么操作(word文字替换怎么弄出来)

  • 微信提到了谁别人能看见吗(微信提到谁别人又把朋友圈删了)

    微信提到了谁别人能看见吗(微信提到谁别人又把朋友圈删了)

  • 健康码添加到桌面不成功(健康码添加到桌面怎么找不到)

    健康码添加到桌面不成功(健康码添加到桌面怎么找不到)

  • 新买的笔记本电脑怎么下载东西(新买的笔记本电脑怎么激活word)

    新买的笔记本电脑怎么下载东西(新买的笔记本电脑怎么激活word)

  • 为什么登录保护关了还要验证(为什么登录保护的设备显示不全)

    为什么登录保护关了还要验证(为什么登录保护的设备显示不全)

  • 微信对话框怎么换样式(微信对话框怎么换气泡)

    微信对话框怎么换样式(微信对话框怎么换气泡)

  • 小米手机传输文件到电脑(小米手机传输文件到电脑太慢)

    小米手机传输文件到电脑(小米手机传输文件到电脑太慢)

  • NT是什么缩写(NT是什么缩写控制器)

    NT是什么缩写(NT是什么缩写控制器)

  • 三星s10是双喇叭吗(三星s10+是双扬声器)

    三星s10是双喇叭吗(三星s10+是双扬声器)

  • 微信互推好友是干嘛的(微信互推啥意思)

    微信互推好友是干嘛的(微信互推啥意思)

  • word文件乱码怎么修复(word文档乱码)

    word文件乱码怎么修复(word文档乱码)

  • 微信怎么关闭手势密码(微信怎么关闭手机联系人添加好友)

    微信怎么关闭手势密码(微信怎么关闭手机联系人添加好友)

  • 电脑过地铁安检有影响吗(电脑过地铁安检需要拿出来吗)

    电脑过地铁安检有影响吗(电脑过地铁安检需要拿出来吗)

  • 苹果手机能解压 zip嘛(苹果手机能解压分卷吗)

    苹果手机能解压 zip嘛(苹果手机能解压分卷吗)

  • 三星s10 有内置红外线嘛(三星s10内置壁纸原图无损)

    三星s10 有内置红外线嘛(三星s10内置壁纸原图无损)

  • 快手怎么看谁看过我的主页(快手怎么看谁看了我的动态)

    快手怎么看谁看过我的主页(快手怎么看谁看了我的动态)

  • 怎么找回删除的未接来电(怎么找回删除的手机短信)

    怎么找回删除的未接来电(怎么找回删除的手机短信)

  • vfx是什么(vfx是什么品牌)

    vfx是什么(vfx是什么品牌)

  • play商店一直核对信息怎么解决(play商店无法登录一直核对)

    play商店一直核对信息怎么解决(play商店无法登录一直核对)

  • vivox27在哪里设置刷脸功能(vivox27在哪里设置字体)

    vivox27在哪里设置刷脸功能(vivox27在哪里设置字体)

  • qq音乐文件在哪里查找(qq音乐文件在哪个文件夹)

    qq音乐文件在哪里查找(qq音乐文件在哪个文件夹)

  • vivox27是全网通吗

    vivox27是全网通吗

  • qq前面的小耳朵是什么(qq前面的小耳朵叫什么)

    qq前面的小耳朵是什么(qq前面的小耳朵叫什么)

  • mx150和mx250的区别(mx250和mx150性能差多少)

    mx150和mx250的区别(mx250和mx150性能差多少)

  • 微信小程序中如何实现微信支付(微信小程序中如何打开不加检验文件的网页)

    微信小程序中如何实现微信支付(微信小程序中如何打开不加检验文件的网页)

  • 酒类的包装物押金可以单独核算吗
  • 社会团体所涉及的法律
  • 资产总额全年季度平均值怎么填写
  • 红字冲回是负数吗
  • 防伪税控开具发票明细表
  • 企业的耕地占用税怎么算
  • 银行存款未达账项包括
  • 实缴年月正常补收
  • 小规模纳税人开专票需要交税吗
  • 年底自查
  • 物业公司减免物业费怎样开票
  • 汇算清缴后需要退税如何操作?
  • 资源税可能计入
  • 增值税总分机构可以汇总纳税吗
  • 增值税减免附加税用计提吗
  • 没有签订合同需要申报印花税吗
  • 生产成本的计算公式是什么
  • linux怎么安装使用conda
  • 穿越火线封号查询官网
  • 单位支付经济补偿金的情形
  • 广告公司员工
  • 盈余公积必须提折旧吗
  • 哪些情形需要办理外债审核登记
  • mac 系统查看
  • php变量底层实现
  • win11打不开英雄连2
  • 羊毛衫变形了还能变回来吗
  • MacOS Big Sur 11.3网页怎么设置时间限制?
  • 电商快递费怎么做账
  • php字符串函数大全
  • 建筑企业如何确认所得税收入
  • 销售合同怎么计提折旧
  • 房地产开发公司组织架构
  • 苹果语音备忘录怎么导出
  • 若依框架是什么框架
  • smarty怎么用
  • 分公司股东怎么填
  • 使用二氧化碳灭火器时人应该站在什么位置
  • thinkphp跨域请求
  • 帝国cms使用手册
  • 发票作废申请书模板
  • 如果企业一直亏损不交所得税会被税局稽查吗
  • 出口不退税需要备案吗
  • 织梦DedeCMS默认文件夹重命名
  • 增值税专用发票几个点
  • 期初库存和期末库存可以修改吗
  • ibm.data.db2
  • 外贸出口备案需准备什么资料
  • 现金流量表里支付的各项税费包括什么
  • 未开票收入确认错属期滞纳金怎么办
  • 企业银行基本户和一般户的区别
  • 计入资本公积的固定资产转出
  • 行政事业单位应用方案总账,财务分析
  • 取报销凭证的步骤
  • 费用摊销怎么做分录
  • 公转私怎么操作
  • 应付职工薪酬为负数什么意思
  • 现金投资属于什么会计科目
  • 公司的私账
  • 如何将windows安装到u盘
  • macOS 10.12.2下PDF崩溃严重怎么回事 macOS 10.12.2下PDF崩溃的原因以及解决办法
  • 利用arp指令,能够防止arp欺骗吗?
  • win8最新版本
  • mac如何重装系统win10
  • webcolct.exe - webcolct 是什么进程
  • 打开win七
  • 批处理命令在哪个菜单中
  • Android -- service两种启动方式startService与bindService
  • 小葵花妈妈课堂开课了是什么药
  • nodejs fs.open
  • android listView二级目录选中效果
  • javascript例题
  • js对象的常用方法
  • jQuery UI Bootstrap是什么?
  • asx文件的作用
  • 山东省省级政务服务区有哪些
  • 国税干部任前谈心谈话
  • 河南地税网上个税怎么交
  • 税务师报考条件和时间2021湖北
  • 增值税普通发票可以抵扣吗
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设