【Vue3-Element-Admin 动态路由】涉及到的页面配置

本文主要是介绍【Vue3-Element-Admin 动态路由】涉及到的页面配置,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Vue3-Element-Admin 动态路由 涉及到的页面配置

  • 0. Vue3-Element-Admin 项目地址
  • 1. router/index.ts
  • 2. Mock接口模拟数据
  • 3. store/permission
  • 4. api/menu
  • 5. plugins/permission

这篇文章讲的主要是 Vue3-Element-Admin 差不多内置的动态路由配置 (根据后端接口渲染)

先把开发环境(.env.development)中的 VITE_MOCK_DEV_SERVER 设置为 true 这代表启用 Mock 服务
Mock 数据模拟 在 vite 中已经配置好了
在这里插入图片描述

0. Vue3-Element-Admin 项目地址

Vue3-Element-Admin:Vue3-Element-Admin

1. router/index.ts

这个文件主要放一些静态初始路由,可以不用管

import type { App } from 'vue'
import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router'export const Layout = () => import('@/layout/index.vue')// 静态路由
export const constantRoutes: RouteRecordRaw[] = [{path: '/redirect',component: Layout,meta: { hidden: true },children: [{path: '/redirect/:path(.*)',component: () => import('@/views/redirect/index.vue')}]},{path: '/login',component: () => import('@/views/login/index.vue'),meta: { hidden: true }},{path: '/',name: '/',component: Layout,redirect: '/dashboard',children: [{path: 'dashboard',component: () => import('@/views/dashboard/index.vue'),name: 'Dashboard', // 用于 keep-alive, 必须与SFC自动推导或者显示声明的组件name一致// https://cn.vuejs.org/guide/built-ins/keep-alive.html#include-excludemeta: {title: 'dashboard',icon: 'homepage',affix: true,keepAlive: true,alwaysShow: false}},{path: '401',component: () => import('@/views/error-page/401.vue'),meta: { hidden: true }},{path: '404',component: () => import('@/views/error-page/404.vue'),meta: { hidden: true }}]}
]/*** 创建路由*/
const router = createRouter({history: createWebHistory(),routes: constantRoutes,// 刷新时,滚动条位置还原scrollBehavior: () => ({ left: 0, top: 0 })
})// 全局注册 router
export function setupRouter(app: App<Element>) {app.use(router)
}/*** 重置路由*/
export function resetRouter() {router.replace({ path: '/login' })
}export default router

2. Mock接口模拟数据

如果目前没有后端接口支持的话,可以先去文件根目录 mock 文件夹中的 menu.mock.ts 查看,一开始可能会有很多数据,全改成我的就好,可以先模拟看一下

import { defineMock } from './base'export default defineMock([{url: 'menus/routes',method: ['GET'],body: {code: '00000',data: [{path: '/dashboard',component: 'Dashboard',redirect: '/dashboard',name: '/dashboard',meta: {title: '首页',icon: 'dashboard',hidden: true,roles: ['ADMIN'],alwaysShow: false,params: null}},{path: '/nihao',component: 'Layout',redirect: '/nihao/hello',name: '/nihao',meta: {title: '你好',icon: 'system',hidden: false,roles: ['ADMIN'],alwaysShow: true,params: null},children: [{path: 'hello',component: 'nihao/hello/index',name: 'Hello',meta: {title: 'Hello',icon: 'user',hidden: false,roles: ['ADMIN'],keepAlive: true,alwaysShow: false,params: null}}]},{path: '/system',component: 'Layout',redirect: '/system/user',name: '/system',meta: {title: '系统管理',icon: 'system',hidden: false,roles: ['ADMIN'],alwaysShow: true,params: null},children: [{path: 'user',component: 'system/user/index',name: 'User',meta: {title: 'Test1',icon: 'user',hidden: false,roles: ['ADMIN'],keepAlive: true,alwaysShow: false,params: null}},{path: 'user',component: 'system/user/index',name: 'User',meta: {title: 'Test2',icon: 'user',hidden: false,roles: ['ADMIN'],keepAlive: true,alwaysShow: false,params: null}}]}],msg: '一切ok'}}// ... 其他接口
])

3. store/permission

查看权限配置相关页面,这边主要是做一些角色鉴权、角色菜单权限,差不多都是菜单相关配置,主要看一下 generateRoutes 方法,它是配置动态路由所需要用到的方法,这边我是使用了我上面那个 Mock 接口,你可以看到
MenuAPI.getRoutes() .then(data => { //... })

import { RouteRecordRaw } from 'vue-router'
import { constantRoutes } from '@/router'
import { store } from '@/store'
import MenuAPI from '@/api/menu'
import { RouteVO } from '@/api/menu/model'const modules = import.meta.glob('../../views/**/**.vue')
const Layout = () => import('@/layout/index.vue')/*** Use meta.role to determine if the current user has permission** @param roles 用户角色集合* @param route 路由* @returns*/
const hasPermission = (roles: string[], route: RouteRecordRaw) => {if (route.meta && route.meta.roles) {// 角色【超级管理员】拥有所有权限,忽略校验if (roles.includes('ROOT')) {return true}return roles.some(role => {if (route.meta?.roles) {return route.meta.roles.includes(role)}})}return false
}/*** 递归过滤有权限的动态路由** @param routes 接口返回所有的动态路由* @param roles 用户角色集合* @returns 返回用户有权限的动态路由*/
const filterAsyncRoutes = (routes: RouteVO[], roles: string[]) => {const asyncRoutes: RouteRecordRaw[] = []routes.forEach(route => {const tmpRoute = { ...route } as RouteRecordRaw // 深拷贝 route 对象 避免污染if (hasPermission(roles, tmpRoute)) {// 如果是顶级目录,替换为 Layout 组件if (tmpRoute.component?.toString() == 'Layout') {tmpRoute.component = Layout} else {// 如果是子目录,动态加载组件const component = modules[`../../views/${tmpRoute.component}.vue`]if (component) {tmpRoute.component = component} else {tmpRoute.component = modules[`../../views/error-page/404.vue`]}}if (tmpRoute.children) {tmpRoute.children = filterAsyncRoutes(route.children, roles)}asyncRoutes.push(tmpRoute)}})return asyncRoutes
}
// setup
export const usePermissionStore = defineStore('permission', () => {// stateconst routes = ref<RouteRecordRaw[]>([])// actionsfunction setRoutes(newRoutes: RouteRecordRaw[]) {routes.value = constantRoutes.concat(newRoutes)}/*** 生成动态路由** @param roles 用户角色集合* @returns*/function generateRoutes(roles: string[]) {return new Promise<RouteRecordRaw[]>((resolve, reject) => {// 接口获取所有路由MenuAPI.getRoutes().then(data => {// 过滤有权限的动态路由const accessedRoutes = filterAsyncRoutes(data, roles)setRoutes(accessedRoutes)resolve(accessedRoutes)}).catch(error => {reject(error)})})}/*** 获取与激活的顶部菜单项相关的混合模式左侧菜单集合*/const mixLeftMenus = ref<RouteRecordRaw[]>([])function setMixLeftMenus(topMenuPath: string) {const matchedItem = routes.value.find(item => item.path === topMenuPath)if (matchedItem && matchedItem.children) {mixLeftMenus.value = matchedItem.children}}return {routes,setRoutes,generateRoutes,mixLeftMenus,setMixLeftMenus}
})// 非setup
export function usePermissionStoreHook() {return usePermissionStore(store)
}

4. api/menu

上面的 MenuAPI.getRoutes() 就是在 api/menu 里面定义的接口请求

import request from "@/utils/request";
import { MenuQuery, MenuVO, MenuForm, RouteVO } from "./model";class MenuAPI {/*** 获取路由列表*/static getRoutes() {return request<any, RouteVO[]>({url: "/api/v1/menus/routes",method: "get",});}// ... 其它接口
export default MenuAPI;

5. plugins/permission

这个文件内也是一些权限配置,按钮鉴权,路由守卫都放在这里面了,主要看 setupPermission 中的 router.addRoute(route) 跳转时会把动态路由塞到原本路由表内

import router from '@/router'
import { useUserStore, usePermissionStore } from '@/store'
import NProgress from '@/utils/nprogress'
import { RouteRecordRaw } from 'vue-router'
import { TOKEN_KEY } from '@/enums/CacheEnum'// 是否有权限
export function hasAuth(value: string | string[], type: 'button' | 'role' = 'button') {const { roles, perms } = useUserStore().user//「超级管理员」拥有所有的按钮权限if (type === 'button' && roles.includes('ROOT')) {return true}const auths = type === 'button' ? perms : rolesreturn typeof value === 'string'? auths.includes(value): auths.some(perm => {return value.includes(perm)})
}export function setupPermission() {// 白名单路由const whiteList = ['/login', '/404']router.beforeEach(async (to, from, next) => {NProgress.start()const hasToken = localStorage.getItem(TOKEN_KEY)if (hasToken) {if (to.path === '/login') {// 如果已登录,跳转首页next({ path: '/' })NProgress.done()} else {const userStore = useUserStore()const hasRoles = userStore.user.roles && userStore.user.roles.length > 0if (hasRoles) {// 未匹配到任何路由,跳转404if (to.matched.length === 0) {from.name ? next({ name: from.name }) : next('/404')} else {next()}} else {const permissionStore = usePermissionStore()try {const { roles } = await userStore.getUserInfo()const accessRoutes = await permissionStore.generateRoutes(roles)accessRoutes.forEach((route: RouteRecordRaw) => {router.addRoute(route)})next({ ...to, replace: true })} catch (error) {// 移除 token 并跳转登录页await userStore.resetToken()next(`/login?redirect=${to.path}`)NProgress.done()}}}} else {// 未登录可以访问白名单页面if (whiteList.indexOf(to.path) !== -1) {next()} else {next(`/login?redirect=${to.path}`)NProgress.done()}}})router.afterEach(() => {NProgress.done()})
}

差不多是这样的,大概页面就这样了
在这里插入图片描述

这篇关于【Vue3-Element-Admin 动态路由】涉及到的页面配置的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1029427

相关文章

Linux 安装、配置Tomcat 的HTTPS

Linux 安装 、配置Tomcat的HTTPS 安装Tomcat 这里选择的是 tomcat 10.X ,需要Java 11及更高版本 Binary Distributions ->Core->选择 tar.gz包 下载、上传到内网服务器 /opt 目录tar -xzf 解压将解压的根目录改名为 tomat-10 并移动到 /opt 下, 形成个人习惯的路径 /opt/tomcat-10

uniapp接入微信小程序原生代码配置方案(优化版)

uniapp项目需要把微信小程序原生语法的功能代码嵌套过来,无需把原生代码转换为uniapp,可以配置拷贝的方式集成过来 1、拷贝代码包到src目录 2、vue.config.js中配置原生代码包直接拷贝到编译目录中 3、pages.json中配置分包目录,原生入口组件的路径 4、manifest.json中配置分包,使用原生组件 5、需要把原生代码包里的页面修改成组件的方

JAVA读取MongoDB中的二进制图片并显示在页面上

1:Jsp页面: <td><img src="${ctx}/mongoImg/show"></td> 2:xml配置: <?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001

vue, 左右布局宽,可拖动改变

1:建立一个draggableMixin.js  混入的方式使用 2:代码如下draggableMixin.js  export default {data() {return {leftWidth: 330,isDragging: false,startX: 0,startWidth: 0,};},methods: {startDragging(e) {this.isDragging = tr

JavaScript全屏,监听页面是否全屏

在JavaScript中,直接监听浏览器是否进入全屏模式并不直接支持,因为全屏API主要是关于请求和退出全屏模式的,而没有直接的监听器可以告知页面何时进入或退出全屏模式。但是,你可以通过在你的代码中跟踪全屏状态的改变来模拟这个功能。 以下是一个基本的示例,展示了如何使用全屏API来请求全屏模式,并在请求成功或失败时更新一个状态变量: javascriptlet isInFullscreen =

IDEA配置Tomcat远程调试

因为不想把本地的Tomcat配置改乱或者多人开发项目想测试,本文主要是记录一下,IDEA使用Tomcat远程调试的配置过程,免得一段时间不去配置到时候忘记(毕竟这次是因为忘了,所以才打算记录的…) 首先在catalina.sh添加以下内容 JAVA_OPTS="-Dcom.sun.management.jmxremote=-Dcom.sun.management.jmxremote.port

vue项目集成CanvasEditor实现Word在线编辑器

CanvasEditor实现Word在线编辑器 官网文档:https://hufe.club/canvas-editor-docs/guide/schema.html 源码地址:https://github.com/Hufe921/canvas-editor 前提声明: 由于CanvasEditor目前不支持vue、react 等框架开箱即用版,所以需要我们去Git下载源码,拿到其中两个主

React+TS前台项目实战(十七)-- 全局常用组件Dropdown封装

文章目录 前言Dropdown组件1. 功能分析2. 代码+详细注释3. 使用方式4. 效果展示 总结 前言 今天这篇主要讲全局Dropdown组件封装,可根据UI设计师要求自定义修改。 Dropdown组件 1. 功能分析 (1)通过position属性,可以控制下拉选项的位置 (2)通过传入width属性, 可以自定义下拉选项的宽度 (3)通过传入classN

js+css二级导航

效果 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Con

基于Springboot + vue 的抗疫物质管理系统的设计与实现

目录 📚 前言 📑摘要 📑系统流程 📚 系统架构设计 📚 数据库设计 📚 系统功能的具体实现    💬 系统登录注册 系统登录 登录界面   用户添加  💬 抗疫列表展示模块     区域信息管理 添加物资详情 抗疫物资列表展示 抗疫物资申请 抗疫物资审核 ✒️ 源码实现 💖 源码获取 😁 联系方式 📚 前言 📑博客主页: