S11-03 Vue-路由
[TOC]
前言
路由发展
- 后端路由阶段
- 前后端分离阶段
- 单页面富应用(SPA)
后端路由阶段
服务器直接生产渲染好对应的HTML页面, 返回给客户端进行展示
一个页面有自己对应的网址, 也就是URL
。URL会发送到服务器
, 服务器会通过正则对该URL进行匹配, 并且最后交给一个Controller
进行处理。Controller进行各种处理, 最终生成HTML或者数据, 返回给前端
优点:
- 1、渲染好的页面, 不需要单独加载任何的js和css, 可以直接交给浏览器展示
- 2、有利于SEO的优化
缺点:
- 整个页面的模块由后端人员来编写和维护
- 前端开发人员如果要开发页面, 需要通过PHP和Java等语言来编写页面代码
- HTML代码和数据以及对应的逻辑会混在一起, 编写和维护困难
前后端分离阶段
后端
只提供API
来返回数据,前端
通过Ajax
获取数据,并且可以通过JavaScript将数据渲染到页面中
优点:
- 前后端责任的清晰,后端专注于数据上,前端专注于交互和可视化
- 当移动端(iOS/Android)出现后,后端不需要进行任何处理,依然使用之前的一套API
路由模式
- URL的hash
- HTML5的History
URL的hash
URL的hash也就是锚点(#
), 本质上是改变window.location
的href属性。我们可以通过直接赋值location.hash
来改变href, 但是页面不发生刷新
优点:
- 兼容性更好,在老版IE中都可以运行
缺点:
- 有一个#,显得不像一个真实的路径
示例:
HTML5的History
history接口是HTML5新增的, 它有六种模式改变URL而不刷新页面
- history.replaceState:替换原来的路径
- history.pushState:使用新的路径
- history.popState:路径的回退
- history.go:向前或向后改变路径
- history.forward:向前改变路径
- history.back:向后改变路径
示例:
基础
vue-router概述
目前前端流行的三大框架, 都有自己的路由实现:Angular的ngRouter,React的ReactRouter,Vue的vue-router
vue-router是基于路由和组件的:
路由
用于设定访问路径, 将路径
和组件
映射起来。- 在vue-router的
单页面应用
中, 页面的路径
的改变就是组件的切换
安装
# 安装4.x版本的vue-router
npm install vue-router@4
基本使用
步骤:
- 1、创建路由组件
- 2、配置路由映射: 组件和路径映射关系的
routes
数组 - 3、创建路由对象:通过
createRouter
创建路由对象,并且传入routes和history模式 - 4、使用路由:通过
<router-link>
和<router-view>
示例:
- router/index.js
- main.js
- app.vue
router-link
属性:
- to:String | Object。表示目标路由的链接。当被点击后,内部会立刻把
to
的值传到router.push()
- replace:Bolean,默认
false
。设置replace
属性的话,当点击时,会调用router.replace()
。导航后不会留下历史记录 - active-class:String,默认
router-link-active
。链接激活时,应用于渲染的<a>
的 class。 - exact-active-class:String,默认
router-link-exact-active
。链接精准激活时,应用于渲染的<a>
的 class。 - custom:Boolean,默认
false
。<router-link>
是否应该将其内容包裹在<a>
元素中 - v-slot:{
href
,route
,navigate
,isActive
,isExactActive
}。作用域插槽,暴露底层的定制能力
router-view
属性:
- name:String。如果
<router-view>
设置了name
,叫命名视图。则会渲染对应的路由配置中components
下的相应组件。 - route:String。一个路由地址的所有组件都已被解析(如果所有组件都被懒加载),因此可以显示。
- v-slot:{
Component
,route
} 。<router-view>
暴露了一个v-slot
API,主要使用<transition>
和<keep-alive>
组件来包裹你的路由组件。
router-link的v-slot
VueRouter4添加的用来替代3时期的 tag
属性,并且它更加灵活
使用:
- 1、使用
custom
表示我们整个元素要自定义 - 2、使用
v-slot
来作用域插槽来获取内部传给我们的值- href:解析后的 URL
- route:解析后的规范化的route对象
- navigate:触发导航的函数
- isActive:是否匹配的状态
- isExactActive:是否是精准匹配的状态
router-view的v-slot
router-view也提供给我们一个插槽,可以用于 <transition>
和 <keep-alive>
组件来包裹你的路由组件
v-slot:
- Component:要渲染的组件
- route:解析出的标准化路由对象
使用:
动画:
路由默认路径
让路径默认跳到到首页, 并且渲染首页组件
路由懒加载
当打包构建应用时,JavaScript 包会变得非常大,影响页面加载。如果我们能把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件,这样就会更加高效。
Vue Router 支持开箱即用的动态导入,这意味着你可以用动态导入代替静态导入:
component
可以传入一个组件,也可以接收一个函数,该函数需要返回一个Promise,而import函数就是返回一个Promise
组件按组分块
想把某个路由下的所有组件都打包在同个异步块 (chunk) 中。只需要使用命名 chunk
,一个特殊的注释语法来提供 chunk name (需要 Webpack > 2.4):
动态路由匹配
基本使用
很多时候,我们需要将给定匹配模式的路由映射到同一个组件。例如,我们可能有一个 User
组件,它应该对所有用户进行渲染,但用户 ID 不同。在 Vue Router 中,我们可以在路径中使用一个动态字段来实现,我们称之为 路径参数 :
route映射:
组件:
router-link:
组件中获取路径参数
template:
$route.params.id
options:
this.$route.params.id
composition:
useRoute().params.id
匹配多个参数
可以在同一个路由中设置有多个 路径参数,它们会映射到 $route.params
上的相应字段
匹配所有路由或Not found路由
常规参数只匹配 url 片段之间的字符,用 /
分隔。如果我们想匹配任意路径,我们可以使用自定义的 路径参数 正则表达式,在 路径参数 后面的括号中加入 正则表达式 :
通过 $route.params.pathMatch
获取到传入的参数
在这个特定的场景中,我们在括号之间使用了自定义正则表达式,并将pathMatch
参数标记为可选可重复*。这样做是为了让我们在需要的时候,可以通过将 path
拆分成一个数组,直接导航到路由:
嵌套路由
基本使用
路由映射:
根组件:
User组件:
匹配到嵌套子路由
当你访问 /user/eduardo
时,在 User
的 router-view
里面什么都不会呈现,因为没有匹配到嵌套路由。也许你确实想在那里渲染一些东西。在这种情况下,你可以提供一个空的嵌套路径:
子路由命名
确保导航到 /user/:id
时始终显示嵌套子路由 UserHome
父路由命名
导航到命名父路由而不导航到嵌套子路由
注意: 重新加载页面将始终显示嵌套的子路由,因为它被视为指向路径/users/:id
的导航,而不是命名路由
编程式导航
$router.push()
导航到不同的位置
在 Vue 实例中,你可以通过 $router
访问路由实例。因此你可以调用 this.$router.push
$router.push
会向 history 栈添加一个新的记录,所以,当用户点击浏览器后退按钮时,会回到之前的 URL。
当你点击 <router-link>
时,内部会调用这个方法
注意:如果提供了 path
,params
会被忽略,上述例子中的 query
并不属于这种情况。
由于属性 to
与 router.push
接受的对象种类相同,所以两者的规则完全相同。
router.push
和所有其他导航方法都会返回一个 Promise,让我们可以等到导航完成后才知道是成功还是失败。
$router.replace()
替换当前位置
它的作用类似于 router.push
,唯一不同的是,它在导航时不会向 history 添加新记录,它取代了当前的条目。
$router.go()
横跨历史
该方法采用一个整数作为参数,表示在历史堆栈中前进或后退多少步,类似于 window.history.go(n)
。
动态添加路由
对路由的添加通常是通过 routes
选项来完成的,但是在某些情况下,你可能想在应用程序已经运行的时候添加路由。
**应用场景:**根据用户不同的权限,注册不同的路由
语法:
// 动态添加一个【路由】
$router.addRoute(路由对象)
// 动态添加一个【子路由】
$router.addRoute('父路由name', 子路由对象)
示例:
动态添加一个【路由】
动态添加一个【子路由】
动态删除路由
三种删除方式:
- 1、添加一个name相同的路由
- 2、通过removeRoute方法,传入路由的名称
- 3、通过addRoute方法的返回值回调
示例:
1、添加一个name相同的路由
2、通过removeRoute方法,传入路由的名称
3、通过addRoute方法的返回值回调
路由导航守卫
$router.beforeEach
: 全局前置守卫
语法:
参数:
- to:即将要进入的路由目标对象
- from:当前导航正要离开的路由对象
- next:在Vue2中我们是通过next函数来决定如何进行跳转的【Vue3不再推荐】
返回值:
- false:取消当前导航
- undefined | 不返回:进行默认导航
- 一个路由地址:String | Object。跳转到该路由地址
注意:Vue3中利用返回值取代了Vue2中next的作用
示例:
RouteRecord
- path
- component
- name: 路由记录独一无二的名称
- redirect
- children
- alias
- beforeEnter
- props
- sensitive
- strict
- meta: 自定义的数据
$route
- $route.path
- $route.fullPath
- $route.params
- $route.query
- $route.hash
- $route.matched
- $route.name
- $route.meta
**1.$route.path**
字符串,对应当前路由的路径,总是解析为绝对路径,如 "/foo/bar"。
**2.$route.params**
一个 key/value 对象,包含了 动态片段 和 全匹配片段,
如果没有路由参数,就是一个空对象。
**3.$route.query**
一个 key/value 对象,表示 URL 查询参数。
例如,对于路径 /foo?user=1,则有 $route.query.user == 1,
如果没有查询参数,则是个空对象。
**4.$route.hash**
当前路由的 hash 值 (不带 #) ,如果没有 hash 值,则为空字符串。锚点
**5.$route.fullPath**
完成解析后的 URL,包含查询参数和 hash 的完整路径。
**6.$route.matched**
数组,包含当前匹配的路径中所包含的所有片段所对应的配置参数对象。
**7.$route.name 当前路径名字**
**8.$route.meta 路由元信息
$router
- 属性
- $router.currentRoute
- $router.options
- 动态添加、删除路由
- $router.addRoute()
- $router.removeRoute()
- $router.resolve()
- $router.hasRoute()
- $router.getRoutes()
- 导航守卫
- $router.beforeEach()
- $router.beforeResolve()
- $router.afterEach()
- 编程式导航
- $router.push()
- $router.replace()
- $router.back()
- $router.forward()
- $router.go()
- $router.isReady()
- $router.onError()