当前位置: 首页 > wzjs >正文

天津网站制作套餐免费学生网页制作成品代码

天津网站制作套餐,免费学生网页制作成品代码,做cps需要什么样的网站,网站开发人员应该用什么浏览器功能7:路由全局前置守卫 功能6:动态添加路由记录 功能5:侧边栏菜单动态显示 功能4:首页使用Layout布局 功能3:点击登录按钮实现页面跳转 功能2:静态登录界面 功能1:创建前端项目前言 在若依里…

功能7:路由全局前置守卫

功能6:动态添加路由记录
功能5:侧边栏菜单动态显示
功能4:首页使用Layout布局
功能3:点击登录按钮实现页面跳转
功能2:静态登录界面
功能1:创建前端项目

前言

在若依里,addRoute方法是在前置守卫里被调用的。要能实现在浏览器刷新后,能重新从后端服务器获取数据再动态添加。处理逻辑如下:

浏览器刷新 前置守卫 Pinia 后端API 路由器 浏览器 触发 beforeEach 检查权限数据 数据已丢失 重新获取权限 返回权限数据 addRoute 动态路由 完成路由跳转 浏览器刷新 前置守卫 Pinia 后端API 路由器 浏览器

不能像昨天的代码那样,在layout/index.vue这个地方调用。会导致浏览器刷新后,动态添加的路由记录丢失。

一.操作步骤

1. 全局前置守卫设置

在 Vue Router 中通过 router.beforeEach 注册全局前置守卫,用于实现路由拦截和权限控制:
新建文件:src/permission.js

import router from './router'
import Layout from '@/layout/index.vue'
// 匹配views里面所有的.vue文件
const modules = import.meta.glob('@/views/**/*.vue')router.beforeEach((to, from, next) => {console.log(router.getRoutes())if (router.getRoutes().length <= 3) {const data1 = {"name": "System","path": "/system","hidden": false,"redirect": "noRedirect","component": "Layout","alwaysShow": true,"meta": {"title": "系统管理","icon": "system","noCache": false,"link": null},"children": [{"name": "User","path": "user","hidden": false,"component": "system/user/index","meta": {"title": "用户管理","icon": "user","noCache": false,"link": null}},{"name": "Role","path": "role","hidden": false,"component": "system/role/index","meta": {"title": "角色管理","icon": "peoples","noCache": false,"link": null}},{"name": "Menu","path": "menu","hidden": false,"component": "system/menu/index","meta": {"title": "菜单管理","icon": "tree-table","noCache": false,"link": null}},{"name": "Dept","path": "dept","hidden": false,"component": "system/dept/index","meta": {"title": "部门管理","icon": "tree","noCache": false,"link": null}},{"name": "Post","path": "post","hidden": false,"component": "system/post/index","meta": {"title": "岗位管理","icon": "post","noCache": false,"link": null}},{"name": "Dict","path": "dict","hidden": false,"component": "system/dict/index","meta": {"title": "字典管理","icon": "dict","noCache": false,"link": null}},{"name": "Config","path": "config","hidden": false,"component": "system/config/index","meta": {"title": "参数设置","icon": "edit","noCache": false,"link": null}},{"name": "Notice","path": "notice","hidden": false,"component": "system/notice/index","meta": {"title": "通知公告","icon": "message","noCache": false,"link": null}},{"name": "Log","path": "log","hidden": false,"redirect": "noRedirect","component": "ParentView","alwaysShow": true,"meta": {"title": "日志管理","icon": "log","noCache": false,"link": null},"children": [{"name": "Operlog","path": "operlog","hidden": false,"component": "monitor/operlog/index","meta": {"title": "操作日志","icon": "form","noCache": false,"link": null}},{"name": "Logininfor","path": "logininfor","hidden": false,"component": "monitor/logininfor/index","meta": {"title": "登录日志","icon": "logininfor","noCache": false,"link": null}}]}]}const data2 = { "name": "Monitor", "path": "/monitor", "hidden": false, "redirect": "noRedirect", "component": "Layout", "alwaysShow": true, "meta": { "title": "系统监控", "icon": "monitor", "noCache": false, "link": null }, "children": [{ "name": "Online", "path": "online", "hidden": false, "component": "monitor/online/index", "meta": { "title": "在线用户", "icon": "online", "noCache": false, "link": null } }, { "name": "Job", "path": "job", "hidden": false, "component": "monitor/job/index", "meta": { "title": "定时任务", "icon": "job", "noCache": false, "link": null } }, { "name": "Druid", "path": "druid", "hidden": false, "component": "monitor/druid/index", "meta": { "title": "数据监控", "icon": "druid", "noCache": false, "link": null } }, { "name": "Server", "path": "server", "hidden": false, "component": "monitor/server/index", "meta": { "title": "服务监控", "icon": "server", "noCache": false, "link": null } }, { "name": "Cache", "path": "cache", "hidden": false, "component": "monitor/cache/index", "meta": { "title": "缓存监控", "icon": "redis", "noCache": false, "link": null } }, { "name": "CacheList", "path": "cacheList", "hidden": false, "component": "monitor/cache/list", "meta": { "title": "缓存列表", "icon": "redis-list", "noCache": false, "link": null } }] }const data3 = { "name": "Tool", "path": "/tool", "hidden": false, "redirect": "noRedirect", "component": "Layout", "alwaysShow": true, "meta": { "title": "系统工具", "icon": "tool", "noCache": false, "link": null }, "children": [{ "name": "Build", "path": "build", "hidden": false, "component": "tool/build/index", "meta": { "title": "表单构建", "icon": "build", "noCache": false, "link": null } }, { "name": "Gen", "path": "gen", "hidden": false, "component": "tool/gen/index", "meta": { "title": "代码生成", "icon": "code", "noCache": false, "link": null } }, { "name": "Swagger", "path": "swagger", "hidden": false, "component": "tool/swagger/index", "meta": { "title": "系统接口", "icon": "swagger", "noCache": false, "link": null } }] }// const data4 = {"name": "Http://ruoyi.vip","path": "http://ruoyi.vip","hidden": false,"component": "Layout","meta": {"title": "若依官网","icon": "guide","noCache": false,"link": "http://ruoyi.vip"}}const newRouteRecord = [data1, data2, data3]filterAsyncRouter(newRouteRecord)newRouteRecord.forEach(route => {router.addRoute(route) // 动态添加可访问路由表})next({ ...to, replace: true })} else {next()}
})/*** 异步路由过滤器 - 核心路由配置处理器* 功能: * 1. 递归处理路由配置树,动态加载Vue组件* 2. 特殊处理Layout组件和ParentView结构* 3. 规范化路由配置结构* * @param {Array} asyncRouterArr - 原始异步路由配置数组* @returns {Array} 处理后的标准化路由配置数组* * 处理逻辑:* 1. 遍历路由配置,处理子路由配置* 2. 动态加载组件(转换字符串路径为真实组件)* 3. 递归处理嵌套子路由* 4. 清理空children和redirect属性*/
const filterAsyncRouter = (asyncRouterArr) => {asyncRouterArr.filter(routeMap => {// 处理子路由if (routeMap.children) {routeMap.children = filterChildrenForRouter(routeMap.children);}if (routeMap.component) {// Layout 组件特殊处理if (routeMap.component === 'Layout') {routeMap.component = Layout} else {routeMap.component = loadView(routeMap.component)}}// 递归处理子路由if (routeMap.children?.length) {filterAsyncRouter(routeMap.children);} else {delete routeMap.children;delete routeMap.redirect;}return true;});}/*** 子路由结构转换器 - 路由层级扁平化处理器* 功能:* 1. 处理ParentView类型的路由结构* 2. 合并嵌套子路由路径* 3. 将多级路由转换为扁平结构* * @param {Array} childrenArr - 原子路由配置数组* @returns {Array} 转换后的扁平化子路由数组* * 处理逻辑:* 1. 当遇到ParentView组件时,将其子路由提升到当前层级* 2. 合并父级路径到子路由path* 3. 保留普通路由配置*/const filterChildrenForRouter = (childrenArr) => {let children = [];childrenArr.forEach(el => {if (el.children?.length && el.component === 'ParentView') {children.push(...el.children.map(c => ({...c,path: `${el.path}/${c.path}`})));return;}children.push(el);});return children;}/*** 动态组件加载器 - 模块解析器* 功能:* 根据组件路径字符串动态加载Vue组件* * @param {string} view - 组件路径字符串(例: "system/user/index")* @returns {Component} Vue组件* * 处理逻辑:* 1. 遍历预编译的模块集合(modules)* 2. 匹配views目录下的对应组件文件* 3. 返回组件异步加载函数*/const loadView = (view) => {let res;for (const path in modules) {const dir = path.split('views/')[1].split('.vue')[0];if (dir === view) {res = () => modules[path]();}}return res;}

2.全局注册

在main.js里把前置守卫引入。

import './permission' 

3.删除layout里的添加逻辑

将添加路由记录的逻辑移到前置守卫里。

<script setup>
import { ElContainer, ElAside } from 'element-plus'
import Sidebar from './components/Sidebar.vue'
import Navbar from './components/Navbar.vue'
import AppMain from './components/AppMain.vue'const data1 = {"name": "System","path": "/system","hidden": false,"redirect": "noRedirect","component": "Layout","alwaysShow": true,"meta": {"title": "系统管理","icon": "system","noCache": false,"link": null},"children": [{"name": "User","path": "user","hidden": false,"component": "system/user/index","meta": {"title": "用户管理","icon": "user","noCache": false,"link": null}},{"name": "Role","path": "role","hidden": false,"component": "system/role/index","meta": {"title": "角色管理","icon": "peoples","noCache": false,"link": null}},{"name": "Menu","path": "menu","hidden": false,"component": "system/menu/index","meta": {"title": "菜单管理","icon": "tree-table","noCache": false,"link": null}},{"name": "Dept","path": "dept","hidden": false,"component": "system/dept/index","meta": {"title": "部门管理","icon": "tree","noCache": false,"link": null}},{"name": "Post","path": "post","hidden": false,"component": "system/post/index","meta": {"title": "岗位管理","icon": "post","noCache": false,"link": null}},{"name": "Dict","path": "dict","hidden": false,"component": "system/dict/index","meta": {"title": "字典管理","icon": "dict","noCache": false,"link": null}},{"name": "Config","path": "config","hidden": false,"component": "system/config/index","meta": {"title": "参数设置","icon": "edit","noCache": false,"link": null}},{"name": "Notice","path": "notice","hidden": false,"component": "system/notice/index","meta": {"title": "通知公告","icon": "message","noCache": false,"link": null}},{"name": "Log","path": "log","hidden": false,"redirect": "noRedirect","component": "ParentView","alwaysShow": true,"meta": {"title": "日志管理","icon": "log","noCache": false,"link": null},"children": [{"name": "Operlog","path": "operlog","hidden": false,"component": "monitor/operlog/index","meta": {"title": "操作日志","icon": "form","noCache": false,"link": null}},{"name": "Logininfor","path": "logininfor","hidden": false,"component": "monitor/logininfor/index","meta": {"title": "登录日志","icon": "logininfor","noCache": false,"link": null}}]}]}
const data2 = { "name": "Monitor", "path": "/monitor", "hidden": false, "redirect": "noRedirect", "component": "Layout", "alwaysShow": true, "meta": { "title": "系统监控", "icon": "monitor", "noCache": false, "link": null }, "children": [{ "name": "Online", "path": "online", "hidden": false, "component": "monitor/online/index", "meta": { "title": "在线用户", "icon": "online", "noCache": false, "link": null } }, { "name": "Job", "path": "job", "hidden": false, "component": "monitor/job/index", "meta": { "title": "定时任务", "icon": "job", "noCache": false, "link": null } }, { "name": "Druid", "path": "druid", "hidden": false, "component": "monitor/druid/index", "meta": { "title": "数据监控", "icon": "druid", "noCache": false, "link": null } }, { "name": "Server", "path": "server", "hidden": false, "component": "monitor/server/index", "meta": { "title": "服务监控", "icon": "server", "noCache": false, "link": null } }, { "name": "Cache", "path": "cache", "hidden": false, "component": "monitor/cache/index", "meta": { "title": "缓存监控", "icon": "redis", "noCache": false, "link": null } }, { "name": "CacheList", "path": "cacheList", "hidden": false, "component": "monitor/cache/list", "meta": { "title": "缓存列表", "icon": "redis-list", "noCache": false, "link": null } }] }
const data3 = { "name": "Tool", "path": "/tool", "hidden": false, "redirect": "noRedirect", "component": "Layout", "alwaysShow": true, "meta": { "title": "系统工具", "icon": "tool", "noCache": false, "link": null }, "children": [{ "name": "Build", "path": "build", "hidden": false, "component": "tool/build/index", "meta": { "title": "表单构建", "icon": "build", "noCache": false, "link": null } }, { "name": "Gen", "path": "gen", "hidden": false, "component": "tool/gen/index", "meta": { "title": "代码生成", "icon": "code", "noCache": false, "link": null } }, { "name": "Swagger", "path": "swagger", "hidden": false, "component": "tool/swagger/index", "meta": { "title": "系统接口", "icon": "swagger", "noCache": false, "link": null } }] }
// const data4 = {"name": "Http://ruoyi.vip","path": "http://ruoyi.vip","hidden": false,"component": "Layout","meta": {"title": "若依官网","icon": "guide","noCache": false,"link": "http://ruoyi.vip"}}
const menuData = [data1, data2, data3]
</script><template><el-container class="h-screen"><el-aside width="200px"><Sidebar :menu-data="menuData"/></el-aside><el-container><el-header height="48px"><Navbar /></el-header><AppMain /></el-container></el-container>
</template><style>
.el-header {--el-header-padding: 0;height: auto;
}
</style>

二.功能验证

运行项目,浏览器访问http://localhost:5173/system/user。
在这里插入图片描述
点击浏览器刷新,页面也能正常显示。

三.知识点拓展

1. 全局前置守卫(Router Navigation Guards)

作用:在路由跳转前进行权限验证和路由处理
典型应用
• 登录状态验证
• 动态路由加载
• 页面访问权限控制
核心方法

router.beforeEach((to, from, next) => {// 逻辑处理next() // 必须调用next()继续路由流程
})

原理
当发生路由导航时,该守卫会按照注册顺序依次执行。通过next()控制流程:
next():继续后续守卫或路由跳转
next(false):中断当前导航
next('/path'):重定向到指定路径

2. 动态路由加载(addRoute)

核心方法

router.addRoute({path: '/system',component: Layout,children: [...]
})

特点
• 支持嵌套路由动态添加
• 路由信息可存储在Vuex/Pinia中
• 浏览器刷新后需要重新加载

3. 组件懒加载(Code Splitting)

实现方式

// 静态导入
import Home from '@/views/Home.vue'// 动态导入(推荐)
component: () => import('@/views/Home.vue')

优化原理
• Webpack将动态导入的组件单独打包
• 访问时按需加载,提升首屏速度
• 结合import.meta.glob实现批量导入:

const modules = import.meta.glob('@/views/**/*.vue')
// 生成类似:
{'./views/About.vue': () => import('./views/About.vue'),'./views/Home.vue': () => import('./views/Home.vue')
}

4. 路由重定向处理

三种实现方式

// 方式1:静态重定向
redirect: '/dashboard'// 方式2:命名路由重定向 
redirect: { name: 'Home' }// 方式3:动态函数重定向
redirect: to => {return '/custom-path'
}

特殊处理
代码中出现的redirect: "noRedirect"是若依框架的特殊标识,用于:
• 标识不需要重定向的父级路由
• 配合菜单系统处理面包屑导航
• 控制侧边栏菜单的展开状态

5. 路由生命周期管理

关键时间点

  1. 用户刷新页面 → 触发全局守卫
  2. 检查现有路由配置 → 判断是否需要重新加载
  3. 调用API获取最新路由 → 动态添加路由
  4. 使用next({ ...to, replace: true })重试当前路由

注意事项
• 需要处理路由重复添加的情况
• 注意浏览器历史记录的管理
• 建议使用路由白名单机制(如登录页免验证)

四.思考

目前在permission.js和layout/index.vue这两个文件里,都有getRouters接口的返回结果,数据冗余。要将这个数据放在一个什么地方,能让permission.js和layout/index.vue这两个文件都方便获取呢?

http://www.dtcms.com/wzjs/416639.html

相关文章:

  • 什么样的公司开做网站seo哪家强
  • 网站建设背景需要写些什么佛山百度推广公司
  • dede模板做网络优化的公司排名
  • 网站建设工具seo实战技巧
  • 我想建立一个网站不知道怎么做啊广告接单平台有哪些
  • 网站信息内容建设责任制落实情况百度云搜索引擎入口手机版
  • 代码共享网站郑州seo线上推广技术
  • 网站建设win2012做网络优化哪家公司比较好
  • 高密哪里有做网站的下载百度app并安装
  • 电子毕业设计代做网站最近营销热点
  • 网站内容是什么上海网站关键词排名
  • 珠宝类网站建设网站流量数据分析
  • wordpress建站要多久单页面网站如何优化
  • 政府网站安全建设网站推广优化招聘
  • 山西省住房与城乡建设部网站关键词查询
  • 网站建设优化服务公司营销方式和营销策略
  • 黄石网站建设流程百度做推广一般要多少钱
  • 专门建立网站的公司吗北京网站优化合作
  • 建网站要学哪些软件设计网站用什么软件
  • 中国服务器排名前十名搜索引擎优化实训报告
  • 手机网页开发者工具seo外链收录
  • 网站建设做网站好做吗app推广接单渠道
  • 松原疫情最新通报百度seo快速提升排名
  • 东莞网站建设哪里好网站建设的流程及步骤
  • 受欢迎的网站建设公司网络站点推广的方法
  • 加强政府门户网站建设重要性b2b电子商务网站
  • 网站内容的排版布局软文网站发布平台
  • 桶装水网站建设运营推广的方式和渠道有哪些
  • 青岛网站制作永诚山东济南最新事件
  • 丰台网站制作公司网站关键词