第十四节:VueRouter4.x简介、基本用法、路由懒加载(打包分析)、动态路由、路由嵌套、相关Api
一. 简介和基本用法
1. 简介
(官网地址:https://next.router.vuejs.org/zh/introduction.html)
Vue Router 是 Vue.js 的官方路由。它与 Vue.js 核心深度集成,让用 Vue.js 构建单页应用变得轻而易举。功能包括:
- 嵌套路由映射
- 动态路由选择
- 模块化、基于组件的路由配置
- 路由参数、查询、通配符
- 展示由 Vue.js 的过渡系统提供的过渡效果
- 细致的导航控制
- 自动激活 CSS 类的链接
- HTML5 history 模式或 hash 模式
- 可定制的滚动行为
- URL 的正确编码
PS:本章节使用的VueRouter版本为4.0.12
2. 基本用法
(1). 通过VueCli创建项目,并且选择包含VueRouter,会自动导入并生成VueRouter的相关配置文件
A. 核心配置文件:src/router/index.js (默认生成的文件如下,后面自己改造)

import { createRouter, createWebHashHistory } from 'vue-router' import Home from '../views/Home.vue' const routes = [ { path: '/', name: 'Home', component: Home }, { path: '/about', name: 'About', // route level code-splitting // this generates a separate chunk (about.[hash].js) for this route // which is lazy-loaded when the route is visited. component: () => import(/* webpackChunkName: "about" */ '../views/About.vue') } ] const router = createRouter({ history: createWebHashHistory(), routes }) export default router
B. main.js中需要以类似插件的形式导入vuerouter
import { createApp } from 'vue' import App from './App.vue' import router from './router' createApp(App).use(router).mount('#app')
(2). 在Views文件夹里创建两个组件页面 Home.vue 和 About.vue ,代码如下
Home.vue

<template> <div> 我是Home组件 </div> </template> <script> import { ref } from 'vue'; export default { setup() { } } </script> <style scoped> </style>
About.vue

<template> <div> 我是About组件 </div> </template> <script> import { ref } from 'vue'; export default { setup() { } } </script> <style scoped> </style>
(3). 配置路由映射
A. Home组件配置成直接加载,About组件配置成懒加载,并且将About组件打包后生成的名字配置成 about 。
B. 通过createRouter创建路由对象,并且传入routes和Hash模式
C. 配置路由默认路径/,自动跳转到Home组件
代码分享:
import { createRouter, createWebHashHistory } from 'vue-router' import Home from '../views/Home.vue' const routes = [ // 默认路径自动跳转到Home组件 { path: "/", redirect: "/home" }, // 下面匹配规则 { path: '/home', name: 'Home', component: Home }, { path: '/about', name: 'About', component: () => import( /* webpackChunkName: "about" */ '../views/About.vue') } ] const router = createRouter({ history: createWebHashHistory(), routes }) export default router
(4). 配置主页面
在App.vue页面,利用<router-view />进行路由占位显示,利用</router-link>进行路由跳转操作。
PS:<router-view>的作用,用来占位显示 <router-link> 链接到的组件。
App.vue代码如下:

<template> <div> <div class="nav"> <router-link to="/home">Home</router-link> | <router-link to="/about">About</router-link> </div> <router-view /> </div> </template> <script> import { ref } from 'vue'; export default { setup() { } } </script> <style scoped> .nav{ margin-bottom: 20px; } </style>
(5). 运行效果
补充几个知识点:
1. 路由地址的模式
有 hash模式 和 history模式,通过下面代码控制: createWebHashHistory是hash模式,createwebHistory是history模式
import { createRouter, createWebHashHistory, createWebHistory } const router = createRouter({ history: createWebHistory(), routes })
hash模式的地址形式:http://localhost:8080/#/home
history模式的地址形式:http://localhost:8080/home
2. <router-link>内质组件的属性
(1). to属性:是一个字符串,或者是一个对象
(2). replace属性:设置 replace 属性的话,当点击时,会调用 router.replace(),而不是 router.push();
(3). active-class属性:设置激活a元素后应用的class,默认是router-link-active;
(4). exact-active-class属性:链接精准激活时,应用于渲染的 <a> 的 class,默认是router-link-exact-active;
eg: 设置如下代码,选中后的标签效果:
<style scoped> .router-link-active{ color: green; font-weight: bold; } </style>
二. 路由懒加载/打包分析
1. 背景
当打包构建应用时,JavaScript 包会变得非常大,影响页面加载:
如果我们能把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件,这样就会更加高效;
PS:默认运行【npm run build】打包,会生成两个js文件,app.xxxx.js 和 chunk-vendors.xxxx.js ,app.js存放的是自己写的代码,chunk-vendors.js存放的是第三方依赖的代码。
2. 实操
这里可以用webpack的分包知识,Vue Router默认就支持动态来导入组件,从而提高首屏的渲染效率;
用法:component可以传入一个组件,也可以接收一个函数,该函数 需要放回一个Promise;而import函数就是返回一个Promise;同时可以指定打包后生成的名字。
如下:把About组件通过懒加载的方式进行导入,并且指定打包后生成的名字为about
const routes = [ // 空路径自动跳转到Home组件 { path: "/", redirect: "/home" }, // 下面匹配规则 { path: '/home', name: 'Home', component: Home }, { path: '/about', name: 'About', component: () => import( /* webpackChunkName: "about" */ '../views/About.vue') } ]
3. 打包分析
通过【npm run build】进行打包,打包后的文件如下:
三. 路由嵌套
1. 何为路由嵌套?
目前我们匹配的Home、About、User等都属于底层路由,我们在它们之间可以来回进行切换;但是呢,我们Home页面本身,也可能会在多个组件之间来回切换:
比如Home中包括Shops、Monent、Message,它们可以在Home内部来回切换;
这个时候我们就需要使用嵌套路由,在Home中也使用 router-view 来占位之后需要渲染的组件;
2. 实操
(1). 路由配置文件
需要在home组件下增加children节点,在里面配置相应的子路由。
核心代码:
const routes = [ // 空路径自动跳转到Home组件 { path: "/", redirect: "/home" }, // 下面匹配规则 { path: '/home', name: 'Home', component: Home, children: [ //默认显示 { path: '', redirect: '/home/message' }, { path: 'message', component: () => import('../views/HomeMessage.vue') }, { path: 'monent', component: () => import('../views/HomeMonent.vue') }, { path: 'shops', component: () => import('../views/HomeShops.vue') } ] }, { path: '/about', name: 'About', component: () => import( /* webpackChunkName: "about" */ '../views/About.vue') }, { path: '/user', name: 'User', component: () => import( /* webpackChunkName: "user" */ '../views/User.vue') } ]
(2). Home组件
通过router-link进行子页面的跳转,通过router-view进行占位。

<template> <div> 我是Home组件 <div class="home"> <router-link to="/home/message">消息</router-link> <router-link to="/home/monent">动态</router-link> <router-link to="/home/shops">商品</router-link> </div> <!-- 路由占位符 --> <router-view></router-view> </div> </template> <script> import { ref } from 'vue'; export default { setup() { } } </script> <style scoped> .home { margin: 40px 0; } .router-link-active { color: green; font-weight: bold; } </style>
(3). 最终效果
相关地址:http://localhost:8080/home/message http://localhost:8080/home/monent http://localhost:8080/home/shops
四. 动态路由剖析
1. 路由的其它属性
name属性:路由记录独一无二的名称;
meta属性:自定义的数据
2. 动态匹配规则
很多时候我们需要将给定匹配模式的路由映射到同一个组件:
例如,我们可能有一个 User 组件,它应该对所有用户进行渲染,但是用户的ID是不同的;
在Vue Router中,我们可以在路径中使用一个动态字段来实现,我们称之为 路径参数;
3. 获取动态路由的值
(1). 在template模板中
直接通过:$route.params.xxx来获取
<div> 我是User组件 <div>我是传递过来的id值:{{$route.params.id}}</div> </div>
(2). 在created之类的生命周期中
通过 this.$route.params.xxx 获取值
created() { console.log(this.$route.params); console.log(`我是created声明周期中获取的值${this.$route.params.id}`) },
(3). 在setup()中
在setup中,我们要使用 vue-router库给我们提供的一个hook useRoute(注意:不是useRouter);该Hook会返回一个Route对象,对象中保存着当前路由相关的值;
<script> import { useRoute } from 'vue-router'; export default { setup() { const route = useRoute(); console.log(`我是setup中获取的值${route.params.id}`) } } </script>
PS:匹配多个参数
4. 配置NotFound页面
(1). 作用
对于那些没有匹配到的路由,我们通常会匹配到固定的某个页面,比如NotFound的错误页面中,这个时候我们可编写一个动态路由用于匹配所有的页面;
(2). 实操
A. 在所有路由规则的最后,配置如下代码
{ // 表示上面所有路径都匹配不到 path: "/:pathMatch(.*)", component: () => import("../views/NotFound.vue") }
B. 在NotFound页面通过 $route.params.pathMatch 获取到传入的参数
<template> <div> 我是NotFound页面 <div>{{$route.params.pathMatch}}</div> </div> </template>
C. 输入地址:http://localhost:8080/user/134543/testkk/3545 ,如下:
PS:
五. 相关Api
1. 页面的跳转push
(1) methods中
通过this.$router.push实现。
methods: { jumpTo1() { this.$router.push('/about'); } }
(2). setup中
需要引入 userRouter (注:不是userRoute) 这个hooks来实现。
<script> import { useRouter } from 'vue-router'; export default { setup() { var router = useRouter(); const jumpTo2 = () => router.push('/user/10086'); return{ jumpTo2 } } } </script>
在user页面,通过route.params.id获取参数值,即为10086
export default { created() { console.log(this.$route.params); console.log(`我是created声明周期中获取的值${this.$route.params.id}`) }, setup() { const route = useRoute(); console.log(`我是setup中获取的值${route.params.id}`) } }
2. query的方式传参和接收
页面传值代码
import { useRouter } from 'vue-router'; export default { setup() { var router = useRouter();// 测试传参2(query的方式) const jumpTo3=() => { router.push({ path: '/home/test2', query: { name: 'ypf', age: 18 } }) }; return { jumpTo3 } } }
页面接收代码
<script> import { useRoute } from 'vue-router'; export default { setup() { const route=useRoute(); // 1. query类型的接收 console.log(route.query) console.log(route.query.name,route.query.age) } } </script>
3. params的方式传参和接收
跳转代码
var router = useRouter(); // 测试传参3(params的方式, 必须使用name属性跳转,不能用path跳转) const jumpTo4 = () => { router.push({ name: 'test3', params: { name: 'ypf', age: 20 } }); };
接收代码
export default { setup() { const route=useRoute(); // 1. param类型的接收 console.log(route.params) console.log(route.params.name,route.params.age) } }
4. replace替换当前位置
5. 页面的前进和后退
!
- 作 者 : Yaopengfei(姚鹏飞)
- 博客地址 : http://www.cnblogs.com/yaopengfei/
- 声 明1 : 如有错误,欢迎讨论,请勿谩骂^_^。
- 声 明2 : 原创博客请在转载时保留原文链接或在文章开头加上本人博客地址,否则保留追究法律责任的权利。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
2020-10-16 第四节:抢单流程优化3(lua整合限流、购买限制、方法幂等、扣减库存)
2019-10-16 第十节:Linq用法大全(一)
2017-10-16 第三节: EF调用普通SQL语句的两类封装(ExecuteSqlCommand和SqlQuery )
2017-10-16 第二节: 比较EF的Lambda查询和Linq查询写法的区别