vue2-路由Router
Vue 中的路由用于实现单页应用(SPA)中的页面导航。它允许你在不刷新整个页面的情况下,根据不同的 URL 路径显示不同的组件,提供了类似于多页面应用的用户体验。例如,在一个电商应用中,可以通过路由实现从首页到商品详情页、购物车页和用户个人中心页等不同页面的切换
Vue Router(Vue 官方的路由库)通过监听浏览器的 URL 变化,根据预先定义的路由规则,动态地加载和显示相应的组件。它利用了浏览器的
History
API 或者Hash
模式来实现 URL 的管理,前端的路由key是路径,value是组件或者一个function,访问指定路径显示对应内容
SPA 应用的理解:
SPA(Single - Page Application)即单页应用,是一种现代的网页应用架构模式。在 SPA 中,整个应用只有一个 HTML 页面,当用户与应用进行交互(如点击链接、提交表单等)时,不会像传统的多页面应用那样进行整页刷新,而是通过 JavaScript 动态地更新页面的部分内容来呈现不同的视图或功能。例如,像一些大型的 Web 应用,如谷歌文档(Google Docs)和 GitHub,它们的用户体验很流畅,在使用过程中基本感觉不到页面的刷新,这就是典型的 SPA 应用
路由的基本使用
安装vue-router
vue2使用vue-router3版本,vue3使用vue-router4版本
npm i vue-router@3
使用vue-router
import VueRouter from "vue-router"
// vue-router是一个插件库,使用了VueRouter之后,vue可以配置router选项
Vue.use(VueRouter)
创建router
新建一个router文件夹/index.js
import VueRouter from "vue-router" // 自定义的组件
import Apage from "@/components/Bpage.vue";
import Bpage from "@/components/Apage.vue"; // 创建并暴露一个路由
export default new VueRouter({
routes: [
// 如果请求路径是/a,触发a组件
{
path: "/a",
component: Apage
},
// 如果请求路径是/b,触发b组件
{
path: "/b",
component: Bpage
}
] })配置router
import router from "./router"
new Vue({
render: h => h(App),
// 配置引入的router
router:router
}).$mount('#app')
路由状态
路由配置成功,浏览器地址栏的url后会带一个#
http://localhost:8080/#/
实现路由跳转、显示
<template>
<div id="app"> <!-- to指定的不是文件位置,而是路由定义的path-->
<!-- active-class属性可以指定该路由激活时router-link上应用的样式,值是一个css类名 -->
<router-link to="/a" active-class="active">Apage</router-link>
<router-link to="/b" active-class="active">Bpage</router-link> <!-- 指定路由组件呈现的位置 -->
<router-view></router-view>
</div>
</template> <style>
/* 路由被激活时用的样式 */
.active{
font-size: 20px;
color: red;
}
</style>
注意事项
- 路由组件(通过路由匹配切换)通常存放在
pages
文件夹 - 一般组件(使用组件标签应用)通常存放在
components
文件夹。 - 通过切换,隐藏了的路由组件,默认是被销毁掉的,需要的时候再去挂载。
- 每个组件都有自己的
$route
属性,里面存储着自己的路由信息。 - 整个应用只有一个router,可以通过组件的
$router
属性获取到
- 路由组件(通过路由匹配切换)通常存放在
嵌套路由
// 创建并暴露一个路由
export default new VueRouter({
routes: [
// 如果请求路径是/a,触发a组件
{
path: "/a",
component: Apage,
// 通过children 配置多级路由,可以配置多个路由
children: [
{
path: "c", // 路径不需要写/
component: Cpage
}
]
},
// 如果请求路径是/b,触发b组件
{
path: "/b",
component: Bpage
}
]
})
<!-- 父路由 -- >
<template>
<div>
<p>a page</p>
<!-- 此处跳转路径要写完整的路径,父路由path/子路由path,不能只写c-->
<router-link to="/a/c">to c page</router-link>
<!-- 子路由显示位置 -->
<router-view></router-view>
</div>
</template>
路由query参数
路由跳转的时候在url上携带参数
传递参数-字符串写法
<!-- 使用数据绑定语法, 路径后?后拼接参数,多个参数用&连接 -->
<!-- 字符串引号里要使用``包裹-->
<router-link :to="`/a/c?id=${id}&size=${num}`">to c page</router-link>
传递参数-对象写法
<router-link :to="{
// 路径
path:'/a/c',
// 使用query选项指定参数
query:{
id:id,
size:num
}
}">to c page</router-link>
接收参数
在对应的路由页面里
{{$route.query.id}}
{{$route.query.size}}
命名路由
命名路由是给路由定义一个名称。这就像给一个人起名字一样,方便在代码的其他地方通过这个名字来引用特定的路由,而不是使用冗长的路径字符串。它使得路由的跳转和操作更加灵活和可读
给路由命名-通过name属性
export default new VueRouter({
routes: [
// 如果请求路径是/a,触发a组件
{
path: "/a",
component: Apage,
// 通过children 配置多级路由,可以配置多个路由
children: [
{ path: "c", // 子路由跳转路由,不需要写/
component: Cpage,
name:"c_page" // 给路由命名
}
]
}
]
})
路由跳转
<!-- 通过name属性指定跳转到c_page-->
<router-link :to="{name:'c_page'}">to c page</router-link>
<!-- 传递参数在后面写query配置即可-->
路由params参数
params
主要用于在路由路径中定义动态片段,这些动态片段是路由路径的一部分,用于区分不同的资源,query
主要用于传递一些额外的、不影响资源定位的信息,比如搜索关键词、排序方式、分页信息等
声明params参数
children: [
{ path: "c/:id", // 使用占位符声明接收的params参数
component: Cpage,
name: "c_page", // 给路由命名 } ]
传递参数-字符串写法
<router-link :to="`/a/c/${id}`">to c page</router-link>
传递参数-对象写法
对象写法传递params参数 路由跳转必须用name别名,不能用path
<router-link :to="{
name:'c_page',
params:{
id:id
} }"></router-link>
读取参数
{{$route.params.id}}
路由props配置
props是一个用于将路由参数以props的形式传递给组件的选项,让路由组件更方便的收到参数
对象写法-传递的是写死的数据
// 通过children 配置多级路由,可以配置多个路由
children: [
{ path: "c/:id", // 使用占位符声明接收的params参数
component: Cpage,
name: "c_page", // 给路由命名
// 对象写法,key和value会以props形式传递给Cpage组件,需要在组件内接收
props:{
id:1
}
}
]
export default {
name: "Cpage",
props:["id"]
}
布尔值开关写法
// 通过children 配置多级路由,可以配置多个路由
children: [
{ path: "c/:id", // 使用占位符声明接收的params参数
component: Cpage,
name: "c_page", // 给路由命名
// 开启了该选项,会把该路由组件收到的params参数以props的形式传给组件,需要在组件接收
props:true
}
]
export default {
name: "Cpage",
props:["id"]
}
函数写法-同时支持动态params、query
children: [
{ path: "c", // 使用占位符声明接收的params参数
component: Cpage,
name: "c_page", // 给路由命名 // 函数返回值中的每一组key-value都会通过props传递给组件
props($route){
// query参数、params参数 return {id:$route.query.id,p:$route.params.p}
} }
]
export default {
name: "Cpage",
props:["id","p"]
}
router-link的replace
控制路由跳转时操作浏览器历史记录的模式
浏览器的历史记录有两种写入方式:分别为push和replace,默认为push
push
是指将一个新的路由记录添加到浏览器的历史记录栈中。这意味着当用户进行导航操作时,会在历史记录中新增一条记录,就好像在栈顶放入了一个新的元素。例如,在一个网页应用中,用户从首页点击链接进入产品详情页,使用push
操作后,浏览器的历史记录栈中就会新增一条记录,表示用户访问了产品详情页,用户可以通过浏览器的 “后退” 按钮回到之前的首页
与
push
不同,replace
操作是替换当前的路由记录,而不是添加新的记录。它就像是修改了历史记录栈顶的元素,而不是在栈顶添加新元素。还是以网页应用为例,如果用户在登录页面登录成功后,使用replace
操作跳转到用户主页,那么在历史记录中,登录页面的记录会被用户主页的记录替换,用户在用户主页时,点击 “后退” 按钮不会回到登录页面
```html
<!-- 开启replace模式 -->
<router-link to="/a/c" replace>to c page</router-link>
```
编程式路由导航
编程式路由导航是指在 JavaScript 代码中通过调用相关的方法来实现路由跳转,不借助
<router-link>
实现路由跳转,让路由跳转更加灵活
- push形式路由跳转
export default {
name: "Apage",
methods:{
puscCpage(){
// 以push的形式跳转到c_page路由
this.$router.push({
name:"c_page", // name是路由命名name的值
query:{
id:1
}
})
}
}
}
<template>
<div>
<p>a page</p>
<!-- 点击按钮触发路由跳转-->
<button @click="puscCpage"></button>
<router-view></router-view>
</div>
</template>
replace形式路由跳转
<script>
export default {
name: "Apage",
methods:{
replaceCpage(){
// 以replace的形式跳转到c_page路由
this.$router.replace({
name:"c_page", // name是路由命名name的值
query:{
id:1
} })
}
}
}
</script> <template>
<div>
<p>a page</p> <button @click="replaceCpage"></button> <router-view></router-view>
</div>
</template>
路由前进、后退
// 触发前进
this.$router.forward()
// 触发后退
this.$router.back()
// 可以前进也可以后退,传正数 前进指定数的记录,传负数 后退指定数的记录
this.$router.go(3)
缓存路由组件
让不展示的路由组件保持挂载,不被销毁,使用kepp-alive
<!-- include的值是组件的名字-->
<!-- 如果指定多个组件 :include=[组件名字] -->
<!-- 如果不指定include,则是被keep-alive包裹的区域所有的组件-->
<keep-alive include="Cpage">
<router-view></router-view>
</keep-alive>
路由的生命周期钩子
路由组件所独有的两个钩子,用于捕获路由组件的激活状态
export default {
name: "Apage",
// activated:路由组件被激活时触发
activated(){
console.log("activated")
},
//deactivated:路由组件失活时触发
deactivated(){
console.log("deactivated")
}
}
路由守卫
路由守卫是 Vue Router(以及其他路由框架也有类似概念)提供的一种机制,用于在路由跳转过程中进行拦截和处理。它就像是在路由的各个关键节点设置的 “关卡”,可以检查用户是否有权限访问某个页面、在进入或离开页面时执行一些特定的操作,如数据获取、页面过渡动画控制等
路由元信息
路由元信息(
meta
)是在定义路由时可以添加的额外信息,它可以是任何你想要的数据类型,如对象、字符串、数字等。这些信息主要用于在路由守卫或者其他需要获取路由额外信息的场景中使用,是一种灵活的方式来为每个路由配置自定义的属性
const routes = [
{
path: '/login',
component: HomeComponent,
// 自定义的元信息
meta: {
title: '首页',
requiresAuth: false
}
},
{
path: '/admin',
component: AdminComponent,
meta: {
title: '管理页面',
requiresAuth: true
}
}
];
// 读取元信息
this.$route.meta
全局路由守卫
// 创建并暴露一个路由
const router = new VueRouter({
routes:[]
})
export default router
beforeEach前置守卫
在初始化、每次路由跳转之前被调用,可以用来进行全局的权限检查、加载显示等操作
router.beforeEach((to, from, next) => {
// to是即将要进入的目标路由对象
// from是当前正要离开的路由对象
// next是一个函数,用于决定是否继续路由跳转
// 检查用户是否登录,通过检查localStorage中的token来判断
const token = localStorage.getItem('token');
if (to.meta.requiresAuth &&!token) {
// 如果目标路由需要认证(通过路由元信息meta中的requiresAuth字段判断) // 跳转登录页
next('/login');
} else {
// 跳转要跳转的页面
next();
}
});afterEach后置守卫
初始化、每次路由跳转完成后被调用,主要用于执行一些不需要中断路由跳转的操作,如页面标题更新、统计页面访问次数等
router.afterEach((to, from) => {
// 更新页面标题,假设每个路由的meta信息中有title字段用于定义页面标题
document.title = to.meta.title || '默认标题';
});
路由独享守卫
可以在单个路由配置中定义,只对该路由生效。它和全局
beforeEach
守卫类似,但作用范围仅限于特定的路由
routes:[
{
path: '/admin',
component: AdminComponent,
beforeEnter: (to, from, next) => {
// 检查用户是否是管理员,假设通过检查localStorage中的adminToken来判断
const adminToken = localStorage.getItem('adminToken');
if (adminToken) {
next();
} else {
next('/login');
}
}
}
]
组件内路由守卫
beforeRouteEnter
在组件被渲染之前调用,此时组件实例还没有被创建,所以不能访问组件的this,但是可以通过传递给
next
函数的回调来访问组件实例export default {
name: 'Admin',
// 通过路由规则,进入该组件时被调用
beforeRouteEnter(to, from, next) {
// 检查用户是否有权限访问该组件
const authService = {
// 权限检查函数,根据用户的角色或其他条件返回布尔值
checkAccess: () => {
const userRole = 'admin'
// 根据角色判断是否有权限访问
return userRole === 'admin'
}
} // 检查用户是否有权限访问该组件
if (authService.checkAccess()) {
// 如果有权限,则继续导航到目标路由
next()
} else {
// 如果没有权限,则重定向到无权访问页面
next('/unauthorized')
}
},
data() {
return {
message: 'Welcome'
}
}
}
beforeRouteUpdate
在当前路由改变,但是该组件被复用时调用。这对于动态路由参数的组件很有用,可以在这里响应路由参数的变化并更新组件数据
例如,有一个用户详情组件,其路由路径为
/user/:id
,当从/user/1
跳转到/user/2
时,由于组件是复用的(都是UserDetailComponent
),beforeRouteUpdate
就会被调用export default { beforeRouteUpdate(to, from, next) {
// 方法updateData用于更新数据
this.updateData(to.params.id);
next();
}
}
beforeRouteLeave
在离开当前组件对应的路由时调用,可以用于保存未完成的数据、询问用户是否确认离开等操作
export default {
// 通过路由规则,离开该组件时被调用
beforeRouteLeave(to, from, next) {
// 检查是否有未保存的数据
const unsavedData = this.checkUnsavedData();
if (unsavedData) {
// 如果有未保存的数据,弹出确认框询问用户是否确认离开
const confirmLeave = window.confirm('你有未保存的数据,确定要离开吗?');
if (confirmLeave) {
next()
} else {
// false代表中断当前路由操作
next(false)
}
} else {
next()
}
},
}
history和hash模式
- Hash 模式
vue路由默认是hash模式
在 URL 中,#符号及其后面的部分被称为哈希(hash)部分
Hash 模式的路由是基于 URL 的哈希值变化来实现的。当哈希值改变时,浏览器不会向服务器发送请求,而是会触发浏览器的hashchange事件,JavaScript 可以通过监听这个事件来实现页面的局部更新,从而达到切换页面(路由)的效果
兼容性好:几乎所有的浏览器都支持hash模式,包括一些较老的浏览器。
不会发送请求到服务器:这使得在单页应用(SPA)中可以实现无刷新的页面切换,因为服务器不会对哈希部分的变化做出响应,所有的路由切换逻辑都在前端完成。
URL 相对不美观:带有#符号的 URL 可能看起来不够简洁、美观,并且在某些场景下可能会让人感觉比较 “奇怪”,例如在分享链接或者生成静态资源链接时。
- History 模式
- History 模式利用了 HTML5 新增的History API,特别是pushState和replaceState方法
- 通过这些方法,JavaScript 可以改变浏览器的历史记录栈,并且在改变 URL 时不会引起页面的刷新(除非手动刷新),浏览器不会自动发送请求到服务器,而是由前端应用来处理这个路由变化。
- URL 更美观:没有#符号,使得 URL 看起来更像传统的多页应用的链接,更符合用户的认知习惯,在分享链接、搜索引擎优化(SEO)等方面有一定优势。
- 需要服务器配置支持:因为改变后的 URL 和普通的 URL 没有区别,所以当用户直接访问或者刷新一个通过History API修改后的 URL 时,浏览器会向服务器发送请求。这就需要服务器进行配置,将所有的前端路由请求都重定向到应用的入口文件(例如index.html),否则会出现 404 错误。
- 兼容性稍差:虽然现代浏览器都支持History API,但一些较老的浏览器可能不支持,在使用时需要考虑兼容性问题
切换history模式
前端配置
import Vue from 'vue';
import Router from 'vue-router';
Vue.use(Router);
const router = new Router({
// 指定History
mode: 'History',
routes: [ ]
});
export default router;
服务端配置
当使用History模式时,因为浏览器会把修改后的 URL 当作普通的请求发送给服务器,所以需要服务器进行相应的配置,具体参考使用对应的Server的解决方案
vue2-路由Router的更多相关文章
- Android业务组件化之子模块SubModule的拆分以及它们之间的路由Router实现
前言: 前面分析了APP的现状以及业务组件化的一些探讨(Android业务组件化之现状分析与探讨),以及通信的桥梁Scheme的使用(Android业务组件化之URL Scheme使用),今天重点来聊 ...
- vue-router同路由$router.push不跳转一个简单解决方案
vue-router同路由$router.push不跳转一个简单解决方案 vue-router跳转一般是这么写: toCurrentPage: function(thisId){ this.$rout ...
- 8、路由 router
路由:router 用户功能 /user ----> index.html /user/login ----> login.html /user/reg ----> reg.html ...
- vue项目创建步骤 和 路由router知识点
菜单快捷导航: vue项目创建 vue路由router知识点(路径参数.查询参数.命名路由.嵌套路由.命名视图.hash/history模式) 1.创建一个vue项目步骤 (windows环境下).创 ...
- Vue学习笔记-Vue.js-2.X 学习(七)===>脚手架Vue-CLI(路由Router)
脚手架Vue-CLI(路由Router) 一 按装(通过新创建脚手架按装),如果在原来的脚手架上按装直接进图型化界面vue ui的插件按装. 二 使用(上面按装下面步骤自动会生成) 第一步:导入路由对 ...
- 前端 JS 原生 javascript 和 location.hash 实现一个单页应用的路由 router
开篇日常立个flag-- 前言 最近在做一些应用,类似于单页应用,想实现类似于 Vue 路由的效果. 但是个人 Vue 基础四舍五入约等于无,而且看着 Vue-router 吃力+用不起来(因为我的项 ...
- Angular JS入门 (一)事件监听(二)多控制器思想与模块化编程(三)路由router
Angular JS入门 ️将流式结构--->模块化 一.事件监听 1.事件监听 前言 NG框架中通过对元素标签添加[ng-事件名] 指令,来对元素添加事件监听 而事件监听的回调函数需要在con ...
- 【面试题】Vue2动态添加路由 router.addRoute()
Vue2动态添加路由 点击打开视频讲解更加详细 场景: 一般结合VueX和localstorage一起使用 router.addRoutes vue-router4后 已废弃:使用 router.ad ...
- Vue2学习小记-给Vue2路由导航钩子和axios拦截器做个封装
1.写在前面 最近在学习Vue2,遇到有些页面请求数据需要用户登录权限.服务器响应不符预期的问题,但是总不能每个页面都做单独处理吧,于是想到axios提供了拦截器这个好东西,再于是就出现了本文. 2. ...
- vue2路由
我们在前面的学习过程中不管是在学习angular还是vue1,都会遇到二级路由,我们现在先来看一下vue2中的一级路由. 首先要引入的是vue2与路由文件. js代码: <script> ...
随机推荐
- 深入理解JavaScript中的try catch finally
在日常开发中,我们经常使用try catch 来捕捉错误,来提升应用程序的健壮性,但是,大部分时候,只是惯性使用,很少静下来去深入理解一下try catch finally,所以本文将对try cat ...
- Linux (Debian) 安装MySQL 后如何获取登录密码
树莓派安装MySQL后获取登录密码 树莓派基于Debian系统. 成功安装MySQL后 su root vim /etc/mysql/debian.cnf 其中 user 和 password 就是你 ...
- 论文阅读翻译之Deep reinforcement learning from human preferences
论文阅读翻译之Deep reinforcement learning from human preferences 关于 首次发表日期:2024-09-11 论文原文链接:https://arxiv. ...
- face-api.js 学习笔记
参考 Build Real Time Face Detection With JavaScript (youtube get started) face-api.js - JavaScript API ...
- Nuxt Kit中的 Nitro 处理程序
title: Nuxt Kit中的 Nitro 处理程序 date: 2024/9/21 updated: 2024/9/21 author: cmdragon excerpt: 摘要:本文详细介绍了 ...
- OPENLDAP部署完整版(Linux)附一键式脚本
(一)环境信息1,系统环境2,域信息(本章节使用)(二)应用部署1,ladp部署1. yum方式安装OpenLDAP服务2.拷贝数据库配置配置文件,并启动服务3.slappasswd生成OpenLDA ...
- 在 ArkTS 中,如何有效地进行内存管理和避免内存泄漏?
ArkTS 是鸿蒙生态的应用开发语言,它在 TypeScript 的基础上进行了优化和定制,以适应鸿蒙系统的需求. 以下是在 ArkTS 中进行有效的内存管理和避免内存泄漏: 1. 使用 const ...
- 三维医学图像数据扩充:flip and rotate
对于小数据量医学图像进行深度学习使,会由于数据量过小而过拟合.因此我们需要采用数据扩充方法,而flip和rotate又是经常用到的,这里做一个简单的实现. 输入为[batchsize,height, ...
- 淘宝程序员没活硬整?在 Excel 和 VSCode 中购物!
大家好,我是程序员鱼皮,最近某宝网站的改进,属实是有点 "新" 了. 你敢相信这是一个购物网站么? 你可以在 Excel 表格中挑选商品进行购物,还原度极高,这两个图表更是点睛之笔 ...
- Android复习(二)应用资源 --> 动画
没什么好总结的 复制自 https://developer.android.google.cn/guide/topics/resources/animation-resource 有需要的可以查看官方 ...