Vue.js【路由】

初识路由

提到路由Route),一般我们会联想到网络中常见的路由器Router),那么路由和路由器之间有什么关联呢?路由是指路由器从一个接口接收到数据根据数据的目的地址将数据定向传送到另一个接口的行为和动作;而路由器是执行行为和动作的硬件设备,主要用于连接网络,实现不同网络之间的通信和数据传递。

根据技术的不同,Web开发中的路由分为后端路由前端路由 

后端路由的整个过程发生在服务器端,开发者需要在服务器端程序中建立一套后端路由规则。当服务器接收到请求后,会通过路由寻找当前请求的URL地址对应的处理程序。

前端路由的整个过程发生在浏览器端,其特点是当URL地址改变时不需要向服务器发起一个加载新页面的请求,而是在维持当前页面的情况下切换页面中显示的内容。

1.后端路由

后端路由规则和处理程序都是开发人员事先编写的代码。当服务器接收到浏览器的请求后,会通过app.get()方法根据URL地址中的路径寻找对应的处理程序。

下面以Node.js环境中的Express框架中的路由为例,演示后端路由的工作原理如下图所示。

2.前端路由

下面以Vue中的路由为例,演示前端路由的工作原理。

Vue中的路由有Hash模式和HTML5模式,具体介绍如下。

Hash模式

Hash模式的前端路由通过URL中从#”开始的部分实现不同组件之间的切换,#”表示Hash,“#”后面的值称为Hash,该值将用于进行路由匹配。Hash模式前端路由的工作原理如下图所示。

HTML5模式

HTML5模式的URL地址与后端路由的URL地址的风格一致,可以通过URL地址中的路径进行路由匹配。HTML5模式前端路由的工作原理如下图所示。

初识Vue Router

Vue Router有多个版本,其中,Vue Router 4适用于Vue 3,而Vue Router 3适用于Vue 2。由于本书重点讲解Vue 3,所以接下来将基于Vue Router4进行讲解。

Vue Router的基本使用

路由的基本使用步骤分为以下4步。

1.定义路由组件

src\components目录下创建Home.vue文件和About.vue文件。

<!-- Home.vue文件 -->
<template><div class="home-container"><h3>Home组件</h3></div>
</template>
<style scoped>
.home-container {min-height: 150px;background-color: #f2f2f2;padding: 15px;
}
</style>
<!-- About.vue文件 -->
<template><div class="about-container"><h3>About组件</h3></div>
</template>
<style scoped>
.about-container {min-height: 150px;background-color: #f2f2f2;padding: 15px;
}
</style>

2.定义路由链接和路由视图

使用<router-view>标签定义路由视图,该标签会被渲染成当前路由对应的组件。通过<router-link>标签定义路由链接方便在不同组件之间切换。

<template><div class="app-container"><h1>App根组件</h1><router-link to="/home">首页</router-link><router-link to="/about">关于</router-link><hr><router-view></router-view></div>
</template>
<style scoped>
.app-container {text-align: center;font-size: 16px;
}
.app-container a {padding: 10px;color: #000;
}
.app-container a.router-link-active {color: #fff;background-color: #000;
}
</style>

3.创建路由模块

① 在src目录下创建router.js文件作为路由模块,并在该文件中导入路由相关函数

import { createRouter, createWebHashHistory } from 'vue-router'

② 在router.js文件中导入需要被路由控制的Home组件和About组件。

import Home from './components/Home.vue'
import About from './components/About.vue'

③ 在router.js文件中创建路由实例对象

const router = createRouter({history: createWebHashHistory(),routes: [{ path: '/home', component: Home },{ path: '/about', component: About },]
})

注意:

步骤②和③的组件加载方式是一次加载所有组件,除了这种方式外,还可以通过懒加载的方式动态加载组件。

④ 在router.js文件中导出路由实例对象

export default router

下面讲解如何通过懒加载的方式动态加载组件。

删除第②步的代码。将第③步的代码修改为如下代码。

const router = createRouter({history: createWebHashHistory(),routes: [{ path: '/home', component: () => import('./components/Home.vue') },{ path: '/about', component: () => import('./components/About.vue') },]
})

4. 导入并挂载路由模块

src\main.js文件中导入并挂载路由模块。

import { createApp } from 'vue'
import './style.css'
import App from './App.vue'
import router from './router.js'	// 导入路由模块
const app = createApp(App)
app.use(router)		// 挂载路由模块
app.mount('#app')

执行yarn dev命令启动服务。服务启动成功后,在浏览器中访问http://127.0.0.1:5173/,使用路由后的初始页面效果、单击“首页”路由链接后的Home组件的效果、单击“关于”路由链接后的About组件的效果如下图所示。

多学一招:更改路由链接激活项的类名

在默认情况下,路由链接激活项的类名为router-link-active。如果需要更改类名,可以在创建路由实例对象时通过linkActiveClass属性设置一个类名。

const router = createRouter({linkActiveClass: 'router-active',……
})

路由重定向

在开发过程中,可能希望当用户访问不同的路径时,页面中显示同一个组件,这时就需要用到路由重定向。路由重定向可以使用户在访问一个URL地址时,强制跳转到另一个URL地址,从而展示特定的组件。通过路由匹配规则中的redirect属性可以指定一个新的路由地址,从而实现路由重定向。

下面演示路由重定向的使用方法。

修改src\router.js文件,实现当用户访问“/路径时,将路由重定向到“/home路径。

const router = createRouter({history: createWebHashHistory(),routes: [{ path: '/', redirect: '/home' },{ path: '/home', component: import ('./components/Home.vue') },{ path: '/about', component: import('./components/About.vue') }]
})

嵌套路由

嵌套路由是指通过路由实现组件的嵌套展示,它主要由页面结构决定。实际项目中的应用界面通常由多层嵌套的组件组合而成,为了使多层嵌套的组件能够通过路由访问,路由也需要具有嵌套关系,也就是在路由里面嵌套它的子路由。

下面演示嵌套路由的简单配置。

src\router.js文件的路由匹配规则中通过children属性定义子路由匹配规则

routes: [{path: '父路由路径', component: 父组件,children: [{ path: '子路由路径1', component: 子组件1 },{ path: '子路由路径2', component: 子组件2 }]}
]

在组件中定义子路由链接的语法格式如下。

<router-link to="/父路由路径/子路由路径"></router-link>

注意:

当使用children属性定义子路由匹配规则时,子路由的path属性前不要带“/”,否则会永远以根路径开始请求。

步骤2

创建src\components\pages\Tab1.vue文件。

<template><div>Tab1组件</div>
</template>
<style scoped>
div {text-align: left;background-color: #9dc4e5;
}
</style>

步骤3

创建src\components\pages\Tab2.vue文件。

<template><div>Tab2组件</div>
</template>
<style scoped>
div {text-align: left;background-color: #ffba00;
}
</style>

步骤4

component\About.vue文件中添加子路由链接子路由视图

<template><div class="about-container"><h3>About组件</h3><router-link to="/about/tab1">tab1</router-link><router-link to="/about/tab2">tab2</router-link><hr><router-view></router-view></div>
</template>
<style scoped>
.about-container {
min-height: 150px;background-color: #f2f2f2;padding: 15px;
}
.about-container a {padding: 10px;border: 1px solid #ccc;border-radius: 5px;padding: 5px 10px;color: #000;margin: 0 5px;
}
.about-container a.router-link-active {color: #000;background-color: #deebf6;
}
</style>

步骤5

修改src\router.js文件,在routes导入Tab1组件和Tab2组件,并使用children属性定义子路由匹配规则

routes: [{ path: '/', redirect: '/about' },{ path: '/home', component: () => import ('./components/Home.vue') },{path: '/about', component: () => import('./components/About.vue'),children: [{ path: 'tab1', component: () => import ('./components/pages/Tab1.vue') },{ path: 'tab2', component: () => import ('./components/pages/Tab2.vue') }]}]

在浏览器中访问http://127.0.0.1:5173/。页面打开后,会自动重定向到About组件的路由,页面显示About组件;单击“tab1”链接,页面显示About组件中的Tab1组件;单击“tab2”链接,页面显示About组件中的Tab2组件,如下图所示。

动态路由

动态路由概述

动态路由是一种路径不固定的路由,路径中可变的部分被称为动态路径参数Dynamic Segment),使用动态路径参数可以提高路由规则的可复用性。在Vue Router的路由路径中,使用“:参数名”的方式可以在路径中定义动态路径参数。

下面通过代码演示如何定义一个动态路由。

注意

不同动态路径参数的动态路由在进行切换时,由于它们都是指向同一组件,所以Vue不会销毁再重新创建这个组件,而是复用这个组件。如果想要在切换时进行一些操作,就需要在组件内部利用watch来监听路由的变化。

下面演示如何在About组件中监听路由的变化。

About组件中利用watch监听路由的变化。

<script setup>
import { useRoute } from 'vue-router'
import { watch } from 'vue'
const route = useRoute()
watch(() => route.path, path => {console.log('路由路径', path)
})
</script>

在浏览器中访问http://127.0.0.1:5173/依次单击子路由链接“tab1”和“tab2”,监听路由变化的效果,如下图所示。

获取动态路径参数值

获取动态路径参数值的2种方式:使用$route.params获取参数值使用props获取参数值

使用$route.params获取参数值

新建src\components\Movie.vue文件,在该文件中定义3路由链接路由视图

<template><div class="movie-container"><router-link to="/movie/1">电影1</router-link><router-link to="/movie/2">电影2</router-link><router-link to="/movie/3">电影3</router-link><router-view></router-view></div>
</template>
<style>
.movie-container {
min-height: 150px;background-color: #f2f2f2;
}
.movie-container a {padding: 0 5px;font-size: 18px;border: 1px solid #ccc;border-radius: 5px;color: #000;margin: 0 5px;
}
</style>

Movie组件初始页面效果、单击“电影1”链接,跳转到MovieDetails组件的效果,如下图所示。

使用props获取参数值Vue Router允许在路由匹配规则中开启props传参。

① 修改src\components\MovieDetails.vue文件,使用props接收路由规则中匹配到的参数

<template><p>电影{{ id }}页面</p>
</template>
<script setup>
const props = defineProps({id: String
})
</script>

② 在src\router.js文件中,为:id”路径的路由开启props传参

{path: ':id', component: () => import          ('./components/movieDetails.vue'), props: true 
}

命名路由

使用路由时,一般会先在routes属性中配置路由匹配规则,然后在页面中使用<router-link>to属性跳转到指定目标地址。但这种方式存在一些弊端,例如,当目标地址比较复杂时,不便于记忆;当地址发生变化时,需要同步修改所有使用了该地址的代码,会增加开发的工作量。为此,Vue Router提供了命名路由

在定义路由匹配规则时,使用name属性为路由匹配规则定义路由名称,即可实现命名路由。当路由匹配规则有了路由名称后,在定义路由链接或执行某些跳转操作时,可以直接通过路由名称表示相应的路由,不再需要通过路由路径表示相应的路由。

使用命名路由的语法格式如下。

{ path: '路由路径', name: '路由名称', component: 组件 }

注意

命名路由的name属性值不能重复,必须保证是唯一的

<router-link>标签中使用命名路由时,需要动态绑定to属性的值为对象。当使用对象作为to属性的值时,to前面要加一个冒号,表示使用v-bind指令进行绑定。在对象中,通过name属性指定要跳转到的路由名称,使用params属性指定跳转时携带的路由参数,语法格式如下。

<router-link :to="{ name: 路由名称, params: { 参数名: 参数值 } }"></router-link>

使用命名路由实现单击Home组件的“跳转到MovieDetails组件”链接跳转到MovieDetails组件,并在页面中获取id

单击“首页”链接后的页面效果单击“跳转到MovieDetails组件”链接后的页面效果,如下图所示。​​​​​​​

编程式导航

Vue中,页面有两种导航方式,分别是声明式导航和编程式导航。其中,使用<router-link>标签定义导航链接的方式属于声明式导航。而编程式导航是先通过useRouter()函数获取全局路由实例,然后通过调用全局路由实例实现导航。

Vue Router提供了useRouter()函数,使用它可以获取全局路由实例,该全局路由实例中提供了常用的push()方法replace()方法go()方法,获取全局路由实例的示例代码如下。

1.push()方法

push()方法会向历史记录中添加一个新的记录,以编程方式导航到一个新的URL。当用户单击浏览器后退按钮时,会回到之前的URLpush()方法的参数可以是一个字符串路径,或者一个描述地址的对象,示例代码如下。

如果在参数的对象中提供了path,则params会被忽略。为了传递参数,需要提供路由的name或者手动拼接带有参数的path,示例代码如下。

使用push()方法实现单击Home组件的“跳转到MovieDetails组件”链接跳转到MovieDetails组件,并在页面中获取id

2.replace()方法

replace()方法与push()方法类似,都是以编程方式导航到一个新的URLreplace()方法在导航后不会向历史记录中添加新的记录,而是会替换历史记录中的当前记录。

在声明式导航中,为<router-link>标签添加replace属性也能实现与replace()方法类似的效果,示例代码如下。

// 编程式导航
router.replace({ path: '/user' })
<!-- 声明式导航 -->
<router-link :to="{ path: '/user' }" replace></router-link>

3.go()方法

go()方法用于实现前进或后退的效果,其参数表示历史记录中前进或后退的步数,类似于window.history.go(),相应的地址栏也会发生改变。

  • go(1)表示前进一条记录。
  • go(-1)表示后退一条记录。

使用go()方法实现单击MovieDetails组件的“后退”按钮后返回到Home组件的效果。

先单击“首页”链接切换到首页,然后单击“跳转到MovieDetails组件”,查看添加了“后退”按钮的页面效果,如下图所示。

导航守卫

导航守卫用于控制路由的访问权限。例如,访问后台主页时,需要用户处于已登录状态,如果没有登录,则跳转到登录页面。用户在登录页面进行登录操作,若登录成功,则跳转到后台主页;若登录失败,则返回登录页面。

登录功能中使用导航守卫的效果,如下图所示。

导航守卫主要分为全局导航守卫导航独享守卫组件导航守卫

​​​​​​​下面讲解全局导航守卫的定义与使用。

全局导航守卫会拦截每个路由规则,从而对每个路由进行访问权限的控制,定义全局导航守卫的示例代码如下。

每个全局导航守卫方法中接收3个形参:tofromnext

  • to:表示目标路由对象
  • from:表示当前导航正要离开的路由对象
  • next:next函数,如果不接收next()函数,则默认允许用户访问每一个路由;如果接收了next()函数,则必须调用next()函数,否则不允许用户访问任何一个路由。

注意

next()函数具有3种调用方式,分别为next()next(false)next('/'),其中,next()表示执行下一个钩子函数;next(false)表示强制停留在当前页面;next('/')表示跳转到其他地址。

使用全局导航守卫实现当进入MovieDetails组件时,判断当前用户是否登录,如果没有登录则跳转到登录页面,如果已登录则跳转到电影详情页面

先切换到首页,然后单击“跳转到MovieDetails组件”链接,会显示登录页面,说明全局导航守卫拦截成功,如下图所示。​​​​​​​​​​​​​​

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

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

相关文章

【how2j JQuery部分】课后题答案及相关笔记

练习题 <script src"jquery.min.js"></script><script>$(function(){$(tr:odd).css({"background-color":"#f8f8f8"});}); </script> <style> table{border-collapse:collapse;width:90%;} tr{border-bottom-sty…

力扣每日一题108:将有序数组转换为二叉搜索树

题目 简单 给你一个整数数组 nums &#xff0c;其中元素已经按 升序 排列&#xff0c;请你将其转换为一棵 平衡 二叉搜索树。 示例 1&#xff1a; 输入&#xff1a;nums [-10,-3,0,5,9] 输出&#xff1a;[0,-3,9,-10,null,5] 解释&#xff1a;[0,-10,5,null,-3,null,9] 也…

VS编辑器下使用MFC完成学生成绩统计分析系统

背景&#xff1a; &#xff08;一&#xff09;实验目的 通过该实验&#xff0c;使学生掌握windows程序设计的基本方法。掌握学生管理中学生成绩统计分析方面的基本知识&#xff0c;熟练应用数据库技术完成对学生成绩管理活动中各类信息的增加、修改、删除、查询等操作。通过处…

解锁AI的神秘力量:LangChain4j带你步入智能化实践之门

关注微信公众号 “程序员小胖” 每日技术干货&#xff0c;第一时间送达&#xff01; 引言 在数字化转型的浪潮中&#xff0c;人工智能&#xff08;AI&#xff09;正逐渐成为推动企业创新和增长的关键力量。然而&#xff0c;将AI技术融入到日常业务流程并非易事&#xff0c;它…

tr,cut,sort,uniq,seq命令的使用

1.tr tr命令是一个文本处理工具&#xff0c;跟正则表达式&#xff0c;字符串。有替换&#xff0c;压缩&#xff0c;删除的功能。 -s压缩 -d删除 命令1&#xff1a;tr a b。将出现的a替换成b。 输入---aaa---bdd--- 输出---bbb---bdd--- 命令&#xff1a;tr -d [字符1字符…

Xshell7、XFtp无法安装报错问题

报错信息&#xff1a; xshell产品无法安装,请验证来源是否存在,是否可以访问 解决方案&#xff1a; 打开本地路径&#xff1a;C:\Program Files (x86)\InstallShield Installation Information 将次文件删掉&#xff0c;重新点击xshell安装程序&#xff0c;重新安装即可

H5视频付费点播打赏影视系统程序全开源运营版

这是一款视频打赏源码&#xff0c;勿做非法用途&#xff0c;由用户亲测功能完善&#xff0c;源码仅用于学习使用&#xff0c;分享链接是用户云盘&#xff0c;具有时效性&#xff0c;感兴趣的可以去学习。 thinkphp开发&#xff0c;前后端分离设计&#xff0c;支持游客登陆、VIP…

【竞技宝】欧冠:多特淘汰大巴黎进决赛,姆巴佩迷失

多特蒙德在本赛季欧冠半决赛第二回合较量中,跟大巴黎队狭路相逢。赛前,大部分球迷和媒体都看好坐拥姆巴佩的大巴黎队,可以靠着主场作战的优势,逆转多特蒙德晋级欧冠决赛。大巴黎队主场作战确实创造出不少得分机会,只可惜球队运气有些差,射门都打在了多特蒙德横梁上。反观多特蒙…

浅谈消息队列和云存储

1970年代末&#xff0c;消息系统用于管理多主机的打印作业&#xff0c;这种削峰解耦的能力逐渐被标准化为“点对点模型”和稍复杂的“发布订阅模型”&#xff0c;实现了数据处理的分布式协同。随着时代的发展&#xff0c;Kafka&#xff0c;Amazon SQS&#xff0c;RocketMQ&…

国内免费AI聊天机器人(ChatGPT)推荐(下)含ChatGPT4.0版本

作者主页&#xff1a;点击&#xff01; 国内免费AI推荐专栏&#xff1a;点击&#xff01; 创作时间&#xff1a;2024年5月7日10点39分 现在&#xff0c;国内各种免费AI聊天机器人(ChatGPT)层出不穷&#xff0c;功能强大、玩法多样&#xff0c;可以满足你的不同需求。 今天&a…

H7-TOOL的双硬件串口同时运行Modbus主机和从机方法,方便大家Modbus测试验证(2024-05-06)

H7-TOOL的双硬件串口同时运行Modbus主机和从机方法&#xff0c;方便大家Modbus测试验证&#xff08;2024-05-06&#xff09; 使用这种方法&#xff0c;仅使用一个TOOL就可以方便同时运行Modbus主机和从机。 【Modbus专题视频】 可以用来熟悉Modbus协议 BSP视频教程第23期…

VS编辑器下使用MFC完成研究生管理系统设计

背景&#xff1a; &#xff08;一&#xff09;实验目的 通过该实验&#xff0c;使学生掌握windows程序设计的基本方法。掌握学籍管理的基本内容&#xff0c;熟练应用数据库技术和通用组件&#xff0c;实现研究生信息的增、删、改、查功能。通过处理过程对计算机软件系统工作原…

2024最新 Gradle 入门教程

&#x1f680; 2024最新 Gradle 入门教程 &#x1f31f; 博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开发秘籍…

在Mars3d实现cesium的ImageryLayer自定义瓦片的层级与原点

需要自定义瓦片层级和原点&#xff0c;所以需要自己写第三方图层&#xff0c;但是之前写的很多方法&#xff0c;图层控制和显隐以及透明度&#xff0c;需要跟之前的交互一直&#xff0c;改动量太大的话不划算&#xff0c;所以直接看Mars3d的layer基类&#xff0c;把重写的image…

ETCD 简介

ETCD 简介 1-etcd介绍 etcd 是 CoreOS 团队于 2013 年 6 月发起的开源项目&#xff0c;它的目标是构建一个高可用的分布式键值(key-value)数据库。具有以下特点&#xff1a; 简单&#xff1a;安装配置简单&#xff0c;而且提供了 HTTP API 进行交互&#xff0c;使用也很简单键…

数据丢失不慌张,手机数据恢复一键解决!

如今手机已经成为我们生活中不可或缺的一部分。无论是工作、学习还是娱乐&#xff0c;手机都扮演着重要的角色。随着使用时间的增加&#xff0c;手机数据丢失的问题也时常发生。那么手机数据恢复有哪些方法呢&#xff1f;面对这种情况&#xff0c;先不要慌张&#xff0c;本文将…

神经元(科普)

Ⅰ 神经元简介 神经元即神经元细胞&#xff0c;是神经系统最基本的结构和功能单位。 分为细胞体和突起两部分。 细胞体由细胞核、细胞膜、细胞质组成&#xff0c;具有联络和整合输入信息并传出信息的作用。 突起有树突和轴突两种。树突短而分枝多&#xff0c;直接由细胞体…

雪深监测站解析-云境天合

TH-XS2雪深监测站是一种用于监测雪深的设备&#xff0c;它们分布在全国各地的关键区域&#xff0c;如高速公路、铁路沿线、机场等重要交通节点&#xff0c;以及山区、林区等易发生雪灾的地区。这些监测站就像是气象工作者的“眼睛”&#xff0c;时刻关注着雪情的变化&#xff0…

计算机毕业设计Python+Vue.js天气预测系统 中国气象质量采集与可视化 天气数据分析 天气可视化 天气大数据 天气爬虫 大数据毕业设计

摘要 随着科技技术的不断发展&#xff0c;人民物质生活质量不断提高&#xff0c;我们越来越关注身边的气象、空气等地理环境。对于普通居民我们会选择合适的气象进行出游&#xff0c;提高精神层面的生活质量&#xff1b;对于企业会关注气象变换状况&#xff0c;来定制相关的生产…

【微机原理及接口技术】8086/8088系统时序和微机总线

【微机原理及接口技术】8086/8088系统时序和微机总线 文章目录 【微机原理及接口技术】8086/8088系统时序和微机总线前言一、8086/8088引脚信号和工作模式1.8088 的两种组态模式2.最小组态的引脚信号3.最小组态的总线形成4.最大组态的总线形成 二、8086/8088典型时序1.三种周期…