Vue VueRouter、路由的使用、路由守卫(笔记)
文章目录1. 单页面应用(SPA)2. 路由的理解2.1 什么是路由2.2 路由分类3. 路由的安装与搭建4. 路由的使用4.1 基本使用4.2 嵌套(多级)路由4.3 路由传参5. 路由命名与元信息5.1 命名路由5.2 路由元信息6. 路由的props配置7. 编程式路由导航8. 缓存路由组件9. 路由守卫9.1 路由配置信息9.2 全局路由守卫9.3 路由独享守卫9.4 组件内的守卫9.5
文章目录
1. 单页面应用(SPA)
- SPA (single page web application) 应用
- vue 是单页面应用,所谓单页面应用就是页面发生改变并不会刷新,只是进行路由跳转
- 单页面应用就是根据 hash 值来变化的,当哈希值改变页面不会发生跳转
- vue 的单页面需要借助到 vueRouter 进行路由跳转
2. 路由的理解
2.1 什么是路由
- 一个路由就是一组映射关系(key - value)
- key 为路径, value 可能是 function 或 component
2.2 路由分类
- 后端路由:
- 理解:value 是 function,用于处理客户端提交的请求
- 工作过程:服务器接收到一个请求时,根据请求路径找到匹配的函数来处理请求,返回响应数据
- 前端路由:
- 理解:value 是 component,用于展示页面内容
- 工作过程:当浏览器的路径改变时,对应的组件就会显示
3. 路由的安装与搭建
-
现在如果使用 npm 安装 vue-router 默认为
vue-router4
-
vue-router4
适配Vue3
,vue-router3
适配Vue2
npm i vue-router@3
-
创建
router/index.js
文件import Vue from "vue"; import VueRouter from "vue-router"; // 使用插件,使用路由不分前后 Vue.use(VueRouter) // 导入路由组件 import About from "../components/About" import Home from "../components/Home" // 创建路由并导出 export default new VueRouter({ routes: [ { // 路由对应的路径 path: "/about", // 对应路径展示的组件 component: About }, { path: "/home", component: Home } ] })
import Vue from 'vue' import App from './App.vue' // 导入路径配置 import router from "./router/index" Vue.config.productionTip = false new Vue({ render: h => h(App), // 挂载路由 router }).$mount('#app') // 挂载之后会多两个属性 // $route:每个组件独享的属性 // $router:全局的一个属性
4. 路由的使用
4.1 基本使用
<!--
标签:
router-link:进行路由跳转的按钮,页面会渲染成 a 标签
router-view:对应路由展示的内容
属性:
active-class:对应的路径页,展示对应的 active 样式
to:跳转路由的路径
replace:替换当前浏览器历史记录,路由跳转的时候默认是 push 追加历史记录
-->
<router-link active-class="active" to="/about">点我显示about组件</router-link>
<router-link active-class="active" to="/home">点我显示home组件</router-link>
<router-view></router-view>
注意:
在对路由组件进行切换时,组件会进行创建和销毁
路由组件通常存放在
pages
文件夹,一般组件通常存放在components
文件夹
4.2 嵌套(多级)路由
export default new VueRouter({
routes: [
{
path: "/about",
component: About,
// msg1 和 msg2 为 about 的二级路由
children: [
{
// 一级路由 path 需要加 /,二级路由不需要
path: "news",
component: News
},
{
path: "msg",
component: Msg
}
]
},
{
path: "/home",
component: Home
}
]
})
<!-- 在一级路由中接着写路由 -->
<h2>我是About组件</h2>
<router-link active-class="active" to="/about/news">显示News</router-link>
<router-link active-class="active" to="/about/msg">显示Msg</router-link>
<router-view></router-view>
4.3 路由传参
-
query参数
<!-- 传入参数 --> <!-- 字符串拼接 --> <router-link :to="`/about/msg/detail?id=${item.id}&title=${item.title}`"> {{ item.title }} </router-link> <!-- 对象携带 query 参数 --> <!-- 也可以写 name --> <router-link :to="{ path: '/about/msg/detail', query: { id: item.id, title: item.title, }, }" >{{ item.title }}</router-link>
<!-- 接收参数 --> <router-view></router-view> <!-- 在被 router-view 渲染出的组件,可以接收到对应的参数 --> <!-- $route.query -->
-
params参数
// params 需要路由路径配合 { name: "Demo" path: '/demo/:id/:title', component: Demo, }
<!-- 传入参数 --> <!-- 字符串拼接 --> <router-link :to="`/demo/${item.id}/${item.title}`"> {{ item.title }} </router-link> <!-- 对象携带 params 参数 --> <router-link :to="{ name: 'Demo', params: { id: item.id, title: item.title, }, }" >{{ item.title }}</router-link>
注意:params 传参,使用 to 的对象写法,不能使用 path 配置项,必须使用 name 配置
<!-- 接收参数, $route.params -->
5. 路由命名与元信息
5.1 命名路由
添加 name 属性,可以简化路由跳转
{
path: '/demo',
component: Demo,
children: [
{
path: 'test',
component: Test,
children: [
{
name: 'hello' // 给路由命名
path: 'welcome',
component: Hello,
}
]
}
]
}
<!--简化前,需要写完整的路径 -->
<router-link to="/demo/test/welcome">跳转</router-link>
<!--简化后,直接通过名字跳转 -->
<router-link :to="{name:'hello'}">跳转</router-link>
<!--简化写法配合传递参数 -->
<router-link
:to="{
name: 'hello',
query: {
id: 666,
title: '你好'
}
}"
>跳转</router-link>
5.2 路由元信息
定义路由的时候可以配置 meta
字段:也就是自定义属性
const router = new VueRouter({
routes: [
{
path: '/foo',
component: Foo,
children: [
{
path: 'bar',
component: Bar,
meta: {
requiresAuth: true
}
}
]
}
]
})
6. 路由的props配置
// 传参时的配置
{
name: "Demo"
path: '/demo',
component: Demo,
// 对象式,这种方式只能传入静态数据
props: {flag: true}
// 布尔值,把 params 的参数传递给 Demo 组件,只能操作 params 参数
props: true
// 函数式,这种方式都可以传递,比就好的一种方式
props($router) {
return {
id: $router.query.id,
title: $router.query.title,
}
}
}
// 这里配置项的写法和组件 props 属性是一样的
// 不用担心会重复,因为路由组件是不能通过组件标签名去使用
props: {
id: String,
title: String,
}
7. 编程式路由导航
不借助 <router-link>
进行路由跳转
// 向浏览器中追加一个历史记录
this.$router.push({
// 跳转路径
// 携带参数
})
// 替换当前历史记录
this.$router.replace({
// 跳转路径
// 携带参数
})
// 对浏览器路由历史记录进行操作
// 回退
this.$router.back()
// 前进
this.$router.forward()
// n 正多少就前进多少,n 负多少就后退多少
this.$router.go(n)
8. 缓存路由组件
-
在路由组件进行切换时,组件经过创建销毁
-
使用
<keep-alive>
包裹住的路由组件,创建一次后不会在销毁了,也就是缓存<!-- 需要在组件中添加 name 属性,才能匹配对应的组件 include:字符串或正则表达式。只有名称匹配的组件会被缓存。 exclude:字符串或正则表达式。任何名称匹配的组件都不会被缓存。 max:数字。最多可以缓存多少组件实例。 --> <keep-alive include="news"> <router-view></router-view> </keep-alive> <!-- 单个写法:include="news" 多个写法:include="news,msg" :include="['news', 'msg']" -->
-
使用
<keep-alive>
才会触发的两个生命周期钩子activated(){ console.log("激活时触发,显示该组件时触发") } deactivated(){ console.log("失活时触发,离开该组件时触发") }
9. 路由守卫
9.1 路由配置信息
{
fullPath: "路由路径,会包含 query 和 params 参数",
path: "路由路径,只会包含 params 参数",
name: "路由命名",
hash: "路由模式",
matched: [
// 包含当前路由的所有嵌套路径片段的路由记录,包括父子
],
meta: {
// 路由元信息
},
params: "参数",
query: "参数"
}
9.2 全局路由守卫
//全局前置守卫:初始化时执行、每次路由切换前执行
router.beforeEach((to, from, next) => {
// to:进入哪个路由,配置
// from:从哪个路由来,配置
// next:放行,如果不放行路由将会被拦截
// next 括号中也可以添加跳转路由路径,next('/')、next({path: '/'})、next({name: '/'})
})
//全局后置守卫:初始化时执行、每次路由切换后执行
router.afterEach((to, from) => {
// 后置路由没有 next,都跳完了还怎么拦
})
9.3 路由独享守卫
// 独享直接写在路由配置项中
{
name: "xxx",
path:"xxx/xxx",
component: Xxx,
beforeEnter(to,from,next){ }
}
9.4 组件内的守卫
// 组件内的守卫,要写在组件中
export default {
//进入守卫:通过路由规则,进入该组件时被调用
beforeRouteEnter (to, from, next) { },
//离开守卫:通过路由规则,离开该组件时被调用
beforeRouteLeave (to, from, next) { }
}
9.5 完整的导航解析流程
- 导航被触发。
- 在失活的组件里调用
beforeRouteLeave
守卫。 - 调用全局的
beforeEach
守卫。 - 在重用的组件里调用
beforeRouteUpdate
守卫 (2.2+)。 - 在路由配置里调用
beforeEnter
。 - 解析异步路由组件。
- 在被激活的组件里调用
beforeRouteEnter
。 - 调用全局的
beforeResolve
守卫 (2.5+)。 - 导航被确认。
- 调用全局的
afterEach
钩子。 - 触发 DOM 更新。
- 调用
beforeRouteEnter
守卫中传给next
的回调函数,创建好的组件实例会作为回调函数的参数传入。
10. 路由器的两种工作模式
-
对于一个 url 来说,# 及其后面的内容就是 hash 值
-
hash 值不会包含在 HTTP 请求中,hash 值不会带给服务器,也不会发送请求,这就是单页面的原理
-
hash 模式:
- 地址中永远带着 # 号,不美观
- 若以后将地址通过第三方手机 app 分享,若 app 校验严格,则地址会被标记为不合法。
- 兼容性较好。
-
history 模式:
- 地址干净,美观
- 兼容性和 hash 模式相比略差
- 应用部署上线时需要后端人员支持,解决刷新页面服务端404的问题
如果
vue.config.js
配置publicPath
,则base
需要统一
-
设置两种模式
const router = new VueRouter({ mode: "history/hash" })
-
node 解决 history 模式刷新页面404
const express = require("express") const history = require("connect-history-api-fallback") const app = express() app.use(history())
11. 路由懒加载
-
因为 Vue 是单页面应用,就导致了第一次进入页面的时候,会加载很久
-
可以给路由组件进行懒加载,这样只有访问该组件的时候才会加载
// 写法 { name: "Demo" path: '/demo/:id/:title', component: () => import('./Foo.vue') }
12. 重定向与别名
12.1 重定向
// 当访问根路径时,重定向到 home 页
export default new VueRouter({
routes:[
{
path: "/",
redirect: "/home"
},
]
})
12.2 别名
// 给路由起别名
export default new VueRouter({
routes:[
{
path: "/home",
alias: "/haha",
component: Home
},
]
})
<!-- 可以使用 haha 去代替 home,此时页面的 url 也会变成 haha-->
<router-link to="/haha"></router-link>
更多推荐
所有评论(0)