vue-router查漏补缺

一、动态路由匹配

1.带参数的动态路由匹配
import User from './User.vue'// 这些都会传递给 `createRouter`
const routes = [// 动态字段以冒号开始{ path: '/users/:efg', component: User },
]

这种方式的路由会匹配到/users/abc或者/users/123,路径参数用冒号:表示,并且将值abc放在route.params里面

//当前路由/users/abc
import {useRoute} from "vue-router";
const route = useRoute();
console.log(route.params,"route");  // {efg:abc}

注意: 这种路径匹配不上 /users/abc/name,需要把path修改为/users/:efg/name

const routes = [// 动态字段以冒号开始{ path: '/users/:efg/name', component: User },  //这样能匹配上,
]
console.log(route.params,"route");  //{efg:abc}
//或者下面这种写法====================================================================
const routes = [// 动态字段以冒号开始{ path: '/users/:efg/:hhh', component: User },  //这样能匹配上,
]
console.log(route.params,"route");  //{efg:abc,hhh:name}

具体匹配规则

匹配模式匹配路径route.params
/users/:username/users/eduardo{ username: ‘eduardo’ }
/users/:username/posts/:postId/users/eduardo/posts/123{ username: ‘eduardo’, postId: ‘123’ }
/users-:id(.*)/users-/123{ id: ‘123’ }

需要注意的是,如果路由从/users/abc变到/users/123,因为都是用的同一个component,所以会重复使用,并不会销毁,这就会导致页面不会重新创建,不会触发生命周期钩子,也获取不到最新的route.params,需使用下面的方法来解决

<script setup>
import { watch } from 'vue'
import { useRoute } from 'vue-router'const route = useRoute()watch(() => route.params.id, (newId, oldId) => {// 对路由变化做出响应...
})
</script>

也可以使用beforeRouteUpdate导航守卫

<script setup>
import { onBeforeRouteUpdate } from 'vue-router'
// ...onBeforeRouteUpdate(async (to, from) => {// 对路由变化做出响应...userData.value = await fetchUser(to.params.id)
})
</script>
2.捕获所有路由或 404 Not found 路由

常规参数只匹配url片段之间的字符,用/分隔。如果我们想匹配任意路径,我们可以使用自定义的路径参数正则表达式,在路径参数后面的括号中加入 正则表达式

const routes = [// 将匹配所有内容并将其放在 `route.params.pathMatch` 下{ path: '/:pathMatch(.*)*', name: 'NotFound', component: NotFound },// 将匹配以 `/user-` 开头的所有内容,并将其放在 `route.params.afterUser` 下{ path: '/user-:afterUser(.*)', component: UserGeneric },
]

注意: 这种匹配方式的优先级最低,优先级高低为 /test > /test/:id > /test:afterUser(.*)* > /:pathMatch(.*)*,就一句话,越精准的匹配上,优先级越高

二、路由的匹配语法

路由的匹配可以通过正则来更加灵活、精确的匹配

const routes = [// /:orderId -> 仅匹配数字{ path: '/:orderId(\\d+)' },// /:productName -> 匹配其他任何内容{ path: '/:productName' },
]
const routes = [// /:chapters ->  匹配 /one, /one/two, /one/two/three, 等{ path: '/:chapters+' },// /:chapters -> 匹配 /, /one, /one/two, /one/two/three, 等{ path: '/:chapters*' },
]

这个具体就看官网了,难得写了

1.Sensitive 与 strict 路由配置

默认情况下,所有路由是不区分大小写的,并且能匹配带有或不带有尾部斜线的路由。例如,路由/users将匹配 /users/users/、甚至 /Users/。这种行为可以通过strictsensitive选项来修改,它们既可以应用在整个全局路由上,又可以应用于当前路由上:

const router = createRouter({history: createWebHistory(),routes: [// 将匹配 /users/posva 而非:// - /users/posva/ 当 strict: true// - /Users/posva 当 sensitive: true{ path: '/users/:id', sensitive: true },// 将匹配 /users, /Users, 以及 /users/42 而非 /users/ 或 /users/42/{ path: '/users/:id?' },],strict: true, // 严格匹配,不允许带有尾部斜线sensitive: true, //区分大小写
})

三、嵌套路由

在子路由中的path加/和不加有很大的区别,以 /开头的嵌套路径将被视为根路径

  {path: "/test",name: "test",hidden: false,component: () => import("@/pages/test/test.vue"),children: [{//path: "center",  //path不加 / ,将匹配到http://localhost:9527/#/test/centerpath: "/center",  //path加 /,将匹配到http://localhost:9527/#/centername: "center",component: () => import("@/pages/center/center.vue"),},],},
1.忽略父组件(4.1+版本)
const routes = [{path: "/test",name: "test",hidden: false,// component: () => import("@/pages/test/test.vue"),children: [{path: "center",name: "center",component: () => import("@/pages/center/center.vue"),},],},
]

由于父级没有指定路由组件,顶级<router-view>将跳过父级并仅使用子路由组件。
在这里插入图片描述

  {path: "/test",name: "test",hidden: false,component: () => import("@/pages/test/test.vue"),children: [{path: "center",name: "center",component: () => import("@/pages/center/center.vue"),},],},

在这里插入图片描述

四、命名路由

当创建一个路由时,可以选择给路由一个name

const routes = [{path: '/user/:username',name: 'user', component: User}
]

这个路由name在整个路由中是唯一的,可以通过router.push({ name: 'user', params: { username: 'erina' } })这种方式来进行路由跳转,将创建一个指向 /user/erina的链接。可以通过route.params来获取参数,使用name有很多优点:

  • 没有硬编码的 URL
  • params的自动编码/解码
  • 防止你在 URL 中出现打字错误
  • 不用关心路由嵌套,就算是100层也能直接使用name来直接定位

命名路由通过params来传递参数,一定要使用动态路由,这样才能获取到传递的参数

### 五、命名视图
有时候想同时 (同级) 展示多个视图,而不是嵌套展示,例如创建一个布局,有 sidebar (侧导航) 和 main (主内容) 两个视图,这个时候命名视图就派上用场了。可以在界面中拥有多个单独命名的视图,而不是只有一个单独的出口。如果`router-view`没有设置名字,那么默认为 default```html
<router-view class="view left-sidebar" name="LeftSidebar" />
<router-view class="view main-content" />
<router-view class="view right-sidebar" name="RightSidebar" />
const router = createRouter({history: createWebHashHistory(),routes: [{path: '/',components: {default: Home,// LeftSidebar: LeftSidebar 的缩写LeftSidebar,// 它们与 `<router-view>` 上的 `name` 属性匹配RightSidebar,},},],
})

六、别名

重定向是指当用户访问 /home 时,URL 会被 / 替换,然后匹配成 /。那么什么是别名呢?

/别名为/home,意味着当用户访问/home 时,URL 仍然是 /home,但会被渲染/的内容。

const routes = [{path: '/users',component: UsersLayout,children: [// 为这 3 个 URL 呈现 UserList// - /users// - /users/list// - /people{ path: '', component: UserList, alias: ['/people', 'list'] },],},
]

如果路由有参数,请确保在任何绝对别名中包含它们:

const routes = [{path: '/users/:id',component: UsersByIdLayout,children: [// 为这 3 个 URL 呈现 UserDetails// - /users/24// - /users/24/profile// - /24{ path: 'profile', component: UserDetails, alias: ['/:id', ''] },],},
]

注意 别名的优先级高于匹配到的路径

const routes = [{path: "/homePage",name: "homePage",alias: "/webgpu",  //就算下面有/webgpu的路由,一样会渲染/homePage的内容component: () => import("@/pages/home/children/homePage.vue"),},{path: "/webgpu",name: "webgpu",component: () => import("@/pages/home/children/webgpu.vue"),},
]

七、路由组件传参

props设置为true时,route.params将被设置为组件的props

const routes = [{ path: '/user/:id', component: User, props: true }
]

路由为/user/123456

<!-- User.vue -->
<script setup>
defineProps({id: String   //值为123456
})
</script><template><div>User {{ id }}</div>
</template>

props是一个对象时,它将原样设置为组件props。当 props 是静态的时候很有用。

const routes = [{ path: '/user/:id', component: User, props: {username:"admin"}}
]

可以创建一个返回props的函数。这允许你将参数转换为其他类型,将静态值与基于路由的值相结合等等。

const routes = [{path: '/search',component: SearchUser,props: route => ({ abc: "13456" })}
]

全局传参

<RouterView v-slot="{ Component }"><component:is="Component"view-prop="value"/>
</RouterView>

这样每一个路由组件都能获取到view-prop参数

八、路由守卫

1. 全局路由前置守卫
const router = createRouter({ ... })router.beforeEach((to, from) => {//通过一个路由地址重定向到一个不同的地址,如同调用 router.push(),且可以传入诸如 replace: true 或 name: 'home' 之类的选项。它会中断当前的导航,同时用相同的 from 创建一个新导航。//  return { name: 'Login' } //返回true或者返回undefine来调用下一个守卫//return true// 返回 false 以取消导航return false
})

如果遇到了意料之外的情况,可能会抛出一个Error。这会取消导航并且调用router.onError()注册过的回调

2. 全局解析守卫

你可以用router.beforeResolve注册一个全局守卫。这和router.beforeEach类似,因为它在每次导航时都会触发,不同的是,解析守卫刚好会在导航被确认之前、所有组件内守卫和异步路由组件被解析之后调用

router.beforeResolve((to,from) =>{console.log(to,from,"beforeResolve");
});
3. 在守卫内的全局注入

从 Vue 3.3 开始,你可以在导航守卫内使用inject()方法

// main.ts
const app = createApp(App)
app.provide('global', 'hello injections')// router.ts or main.ts
router.beforeEach((to, from) => {const global = inject('global') // 'hello injections'// a pinia storeconst userStore = useAuthStore()// ...
})
4. 路由独享的守卫

beforeEnter守卫 只在进入路由时触发,不会在 params、query 或 hash 改变时触发。例如,从 /users/2 进入到 /users/3 或者从 /users/2#info 进入到 /users/2#projects。它们只有在 从一个不同的 路由导航时,才会被触发。

function removeQueryParams(to) {if (Object.keys(to.query).length)return { path: to.path, query: {}, hash: to.hash }
}function removeHash(to) {if (to.hash) return { path: to.path, query: to.query, hash: '' }
}const routes = [{path: '/users/:id',component: UserDetails,beforeEnter: [removeQueryParams, removeHash],},{path: '/about',component: UserDetails,beforeEnter: [removeQueryParams],},
]

当配合嵌套路由使用时,父路由和子路由都可以使用beforeEnter。如果放在父级路由上,路由在具有相同父级的子路由之间移动时,它不会被触发。例如:

const routes = [{path: '/user',beforeEnter() {// ...},children: [{ path: 'list', component: UserList },{ path: 'details', component: UserDetails },],},
]

示例中的 beforeEnter 在 /user/list /user/details 之间移动时不会被调用,因为它们共享相同的父级路由。如果我们直接将 beforeEnter 守卫放在details路由上,那么在这两个路由之间移动时就会被调用。

5. 完整的导航解析流程
  • 导航被触发。
  • 在失活的组件里调用 beforeRouteLeave 守卫。
  • 调用全局的 beforeEach 守卫。
  • 在重用的组件里调用 beforeRouteUpdate 守卫(2.2+)。
  • 在路由配置里调用 beforeEnter。
  • 解析异步路由组件。
  • 在被激活的组件里调用 beforeRouteEnter。
  • 调用全局的 beforeResolve 守卫(2.5+)。
  • 导航被确认。
  • 调用全局的 afterEach 钩子。
  • 触发 DOM 更新。
  • 调用 beforeRouteEnter 守卫中传给 next 的回调函数,创建好的组件实例会作为回调函数的参数传入。

九、RouterView 插槽

RotuerView 组件暴露了一个插槽,可以用来渲染路由组件:

<router-view v-slot="{ Component }"><keep-alive><component :is="Component" /></keep-alive>
</router-view>

十、滚动行为

使用前端路由,当切换到新路由时,想要页面滚到顶部,或者是保持原先的滚动位置,就像重新加载页面那样。 vue-router 能做到,而且更好,它让你可以自定义路由切换时页面如何滚动。
注意: 这个功能只在支持 history.pushState 的浏览器中可用。

const router = createRouter({history: createWebHashHistory(),routes: [...],scrollBehavior (to, from, savedPosition) {return {top:10,behavior: 'smooth',  //让滚动更平滑,不是直接跳到这个位置,而是慢慢滚动到这个位置}// return 期望滚动到哪个的位置}
})

也可以通过 el 传递一个 CSS 选择器或一个 DOM 元素。在这种情况下,top 和 left 将被视为该元素的相对偏移量

const router = createRouter({scrollBehavior(to, from, savedPosition) {// 始终在元素 #main 上方滚动 10pxreturn {// 也可以这么写// el: document.getElementById('main'),el: '#main',// 在元素上 10 像素top: 10,}},
})

十一、导航故障

当使用router-link组件时,Vue Router会自动调用router.push来触发一次导航。虽然大多数链接的预期行为是将用户导航到一个新页面,但也有少数情况下用户将留在同一页面上:

  • 用户已经位于他们正在尝试导航到的页面
  • 一个导航守卫通过调用return false中断了这次导航
  • 当前的导航守卫还没有完成时,一个新的导航守卫会出现了
  • 一个导航守卫通过返回一个新的位置,重定向到其他地方 (例如,return ‘/login’)
  • 一个导航守卫抛出了一个Error

注意:导航是异步的
如果导航被阻止,导致用户停留在同一个页面上,由router.push返回的Promise的解析值将是Navigation Failure。否则,它将是一个falsy值(通常是undefined)。这样我们就可以区分我们导航是否离开了当前位置:

const navigationResult = await router.push('/my-profile')if (navigationResult) {// 导航被阻止
} else {// 导航成功 (包括重新导航的情况)this.isMenuOpen = false
}

Navigation Failure 是带有一些额外属性的Error实例,这些属性为我们提供了足够的信息,让我们知道哪些导航被阻止了以及为什么被阻止了。要检查导航结果的性质,请使用isNavigationFailure函数:

import { NavigationFailureType, isNavigationFailure } from 'vue-router'// 试图离开未保存的编辑文本界面
const failure = await router.push('/articles/2')if (isNavigationFailure(failure, NavigationFailureType.aborted)) {// 给用户显示一个小通知showToast('You have unsaved changes, discard and leave anyway?')
}

NavigationFailureType有三种值

  • aborted:在导航守卫中返回false中断了本次导航。
  • cancelled: 在当前导航完成之前又有了一个新的导航。比如,在等待导航守卫的过程中又调用了router.push
  • duplicated:导航被阻止,因为我们已经在目标位置了。

十二、动态路由

router.addRoute({ name: 'admin', path: '/admin', component: Admin })
router.addRoute('admin', { path: 'settings', component: AdminSettings })

动态添加路由有两种方式,上面的第一种是直接添加在最顶级路由,第二种方式传入一个路由的name,可以把第二个参数的路由放在它的children属性中,用于添加嵌套路由,相当于

router.addRoute({name: 'admin',path: '/admin',component: Admin,children: [{ path: 'settings', component: AdminSettings }],
})

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

013路由协议-OSPF

OSPF具有更适用于规模较大的网络环境&#xff0c;收敛更快速、依据带宽来计算路径成本等。 计算方式&#xff1a; 100M/当前端口的带宽 如果小于1就按照1来计算 例如&#xff1a; 当前端口的带宽是1.54M 路径成本 100/1.54 65 当前端口的带宽是 1000M 路径成本 100/100 0.…

快捷构建AI大模型,源码自取可直接运行

Node.js 和 WebSocket 实现一个基于kimi&#xff08;Moonshot 月之暗大模型&#xff09;的AI工具 前端&#xff1a;前端界面比较容易&#xff0c;只需要简单的额css js即可&#xff0c;本文使用vue作为作为demo。 后端&#xff1a;我java很垃圾&#xff0c;写不出好的代码&am…

探索云原生安全解决方案的未来

我们是否充分意识到云端所面临的网络安全威胁&#xff1f; 在当今互联互通的世界中&#xff0c;维护安全的环境至关重要。云的出现扩大了潜在威胁的范围&#xff0c;因为它催生了机器身份&#xff08;称为非人类身份 (NHI)&#xff09;及其秘密。随着组织越来越多地转向云原生…

关于利用 EtherNet/IP 转 Profinet 网关模块实现罗克韦尔变频器接入西门子 PLC 的配置范例

在现代工业自动化领域&#xff0c;不同品牌设备之间的通信兼容性问题一直是企业面临的挑战之一。某智能工厂为了优化生产流程&#xff0c;提高设备的协同工作效率&#xff0c;决定对其生产线上的控制系统进行升级改造。该生产线中&#xff0c;AB罗克韦尔PowerFlex变频器作为关键…

Ajax--实现检测用户名是否存在功能

&#xff08;一&#xff09;什么是Ajax Ajax&#xff08;Asynchronous Javascript And XML&#xff09; 翻译成中文就是“异步JavaScript和XML”&#xff0c;即使用JavaScript与服务器进行异步交互&#xff0c;传输的数据为XML。 AJAX还可以在浏览器实现局部刷新的效果&#xf…

【LC】160. 相交链表

题目描述&#xff1a; 给你两个单链表的头节点 headA 和 headB &#xff0c;请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点&#xff0c;返回 null 。 图示两个链表在节点 c1 开始相交&#xff1a; 题目数据 保证 整个链式结构中不存在环。 注意&…

算法设计1_分治

递归的概念 递归算法&#xff1a;一个直接或间接地调用自身的算法递归函数&#xff1a;使用函数自身给出定义的函数递归方程&#xff1a;对于递归算法&#xff0c;一般可把时间代价表示为一个递归方程解递归方程最常用的方法是进行递归扩展 阶乘函数 边界条件递归关系 n ! {…

基于yolov8的SAR影像目标检测系统,支持图像、视频和摄像实时检测【pytorch框架、python源码】

更多目标检测、图像分类识别、目标追踪等项目可看我主页其他文章 功能演示&#xff1a; 基于yolov8的SAR影像目标检测系统&#xff0c;支持图像、视频和摄像实时检测【pytorch框架、python源码】_哔哩哔哩_bilibili &#xff08;一&#xff09;简介 基于yolov8的SAR影像目标…

uni-app 设置缓存过期时间【跨端开发系列】

&#x1f517; uniapp 跨端开发系列文章&#xff1a;&#x1f380;&#x1f380;&#x1f380; uni-app 组成和跨端原理 【跨端开发系列】 uni-app 各端差异注意事项 【跨端开发系列】uni-app 离线本地存储方案 【跨端开发系列】uni-app UI库、框架、组件选型指南 【跨端开…

复现论文:PromptTA: Prompt-driven Text Adapter for Source-freeDomain Generalization

github&#xff1a;zhanghr2001/PromptTA: Source-free Domain Generalization 论文&#xff1a;[2409.14163] PromptTA: Prompt-driven Text Adapter for Source-free Domain Generalization 自己标注&#xff1a;PromptTA: Prompt-driven Text Adapter for Source-free Domai…

Dos脚本中的start命令

0 Preface/Foreword 1 Start介绍 start是用来启动一个应用或者一个bat脚本文件。 1.1 %*传递参数 %*&#xff1a;表示运行命令时传入的所有参数。 1.2 %processor_architecture% 系统处理器架构&#xff0c;内置变量。 echo %processor_architecture% 1.3 示例 echo He…

HTML笔记()蜘蛛纸牌之卡牌拖拽

效果 代码 <!DOCTYPE html> <html><head><style>body{display: flex;justify-content: center;align-items: center;height: 100vh;background-color: #2b2b2b;position: relative;}.card{/*设置卡牌的外观*/width: 150px;height: 200px;background-…

基于SSM的线上考试系统的设计与实现(计算机毕业设计)+万字说明文档

系统合集跳转 源码获取链接 一、系统环境 运行环境: 最好是java jdk 1.8&#xff0c;我们在这个平台上运行的。其他版本理论上也可以。 IDE环境&#xff1a; Eclipse,Myeclipse,IDEA或者Spring Tool Suite都可以 tomcat环境&#xff1a; Tomcat 7.x,8.x,9.x版本均可 操作系统…

vue 封装全局方法及使用

1.找到项目中的utils定义js&#xff0c;这个js存放全局可使用的方法 2.去项目中main.js中引入注册 import publicFun from ./utils/test Vue.prototype.$publicFun publicFun;3.项目使用 ddd(){this.$publicFun.testwen()},

微信小程序中使用miniprogram-sm-crypto实现SM4加密攻略

在微信小程序开发过程中&#xff0c;数据安全至关重要。本文将为大家介绍如何在微信小程序中使用miniprogram-sm-crypto插件进行SM4加密&#xff0c;确保数据传输的安全性。 一、SM4加密简介 SM4是一种对称加密算法&#xff0c;由国家密码管理局发布&#xff0c;适用于商密领…

【论文阅读】相似误差订正方法在风电短期风速预报中的应用研究

文章目录 概述&#xff1a;摘要1. 引言2. 相似误差订正算法&#xff08;核心&#xff09;3. 订正实验3.1 相似因子选取3.2 相似样本数试验3.3 时间窗时长实验 4. 订正结果分析4.1 评估指标对比4.2 风速曲线对比4.3 分风速段订正效果评估4.4 风速频率统计 5. 结论与讨论 概述&am…

高中数学:计数原理-二项式定理

文章目录 一、二项式定理与通项公式二、二项式系数的性质 一、二项式定理与通项公式 我们先来看完全平方公式 二、二项式系数的性质

javaweb-Mybaits

1.Mybaits入门 &#xff08;1&#xff09;介绍 &#xff08;2&#xff09; 2.Mybaits VS JDBC 3.数据库连接池 &#xff08;1&#xff09;SpringBoot默认连接池为hikari&#xff0c;切换为Druid有两种方式 方式一&#xff1a;加依赖 方式二&#xff1a;直接修改配置文件 …

节点流和处理流

1. 基本介绍 节点流可以从一个特定的数据源读写数据&#xff0c;如FileReader、FileWriter 处理流(也叫包装流)是“连接”在已存在的流(节点流或处理流)之上&#xff0c;为程序提供更为强大的读写功能&#xff0c;也更加灵活&#xff0c;如BufferedReader、BufferedWriter 2. …

21个Python脚本自动执行日常任务(2)

引言 作为编程领域摸爬滚打超过十年的老手&#xff0c;我深刻体会到&#xff0c;自动化那些重复性工作能大大节省我们的时间和精力。 Python以其简洁的语法和功能强大的库支持&#xff0c;成为了编写自动化脚本的首选语言。无论你是专业的程序员&#xff0c;还是希望简化日常工…