路由 概念
- 12.1 什么是路由:路由就是路径和组件的映射关系
- 12.2 为什么要使用路由:因为Vue组件是单页面应用(SPA):所有的功能在一个html上实现,而前端的路由作用就是实现业务场景的切换,说白了路由就是用来组件切换
- 路由的好处就是:整体不刷新,用户体验更好
- 数据传递容易,开发效率高。
- 缺点:首屏加载会比较慢一点,不利于seo
vue-router
- 概念:本质就是一个三方包
- 组件分类:页面组件(在项目中我们把页面组件放在src/wiews文件夹),复用组件(src/components文件夹中)
vue-router的使用
- 1:下载vue-router模块到当前工程 npm i vue-router@3.5.3
- 2:在main.js引入VueRouter函数 import VueRouter from 'vue-router'
- 3:添加到Vue.use()身上,注册全局的router——link和router——view组件 Vue.use(VueRouter)
- 4:创建路由规则数组 :路径和组件名对应的关系
import Vue from 'vue'
import App from './App.vue'
//第一步下包npm i vue-router@3.5.3指定版本,门前最新的router是vue3的
//第二步 导入路由
import VueRouter from 'vue-router'
//第三步 使用路由插件
Vue.use(VueRouter)
// 第四步创建路由规则
import Find from './views/Find.vue'
import My from './views/My.vue'
import Part from './views/Part.vue'
const routes=[
{
path:'/find',
component:Find
},
{
path:'/my',
component:My
},
{
path:'/part',
component: Part
}
]
// 第五步 创建路由对象 -传入规则
const router=new VueRouter({
routes
})
//第六步关联到vue实例
new Vue({
render: h => h(App),
router
}).$mount('#app')
//第七步占位符占位
<router-view></router-view>
-
5:用规则生成路由对象 const router = new VueRouter({ routes })
-
6:把路由对象注入到new Vue 实例中 const router = new VueRouter({ router })
-
7:components换成router-view,用router-view作为挂载点,切换不同的路由页面
<router-view></router-view>
这里需要注意的是router和routes
声明式导航--跳转
- router提供了一个全局组件 router-link
- router-link实质上最终会渲染成a链接 to属性等价于提供 href属性(to无需#)
- router-link提供了声明式导航高亮的功能(自带类名)
- 总结: 链接导航, 用router-link配合to, 实现点击切换路由
声明式导航--传参在router-link上的to属性传值, 语法格式如下
-第一种: /path?参数名=值
<!-- 第一种查询字符串传参 -->
<router-link to="/part?name=小明&age=18&sex=男">查询字符串传参</router-link>
-----------------------------
<!-- 对应的组件页面接收$route.query -->
<h1>我是part页面</h1>
<h1>{{$route.query.name}}</h1>
<h1>{{$route.query.age}}</h1>
<h1>{{$route.query.sex}}</h1>
- 第二种: /path/值 – 需要路由对象提前配置 path: “/path/参数名”
动态路劲传参
第一步路径上/传参
<router-link to="/my/小红/28/女">动态路径传参</router-link>
第二步路由规则上配置
{
path:'/my/:name/:age/:sex',
component:My
},
------------------------- <!-- 对应的组件页面接收$route.params -->
<h1>我是my页面</h1>
<h1>{{$route.params.name}}</h1>
<h1>{{$route.params.age}}</h1>
<h1>{{$route.params.sex}}</h1>
编程式导航
就是利用js代码来跳转和传参,因为声明式导航需要route-link标签的支持,所以有一定的局限性
第一种根据路由规则路径来跳转
<template>
<div>
<div class="footer_wrap">
<!--声明式导航 -->
<!-- <router-link to="/find">发现音乐</router-link>
<router-link to="/my">我的音乐</router-link>
<router-link to="/part">朋友</router-link> -->
<!-- 编程式导航跳转--根据路径跳转 -->
<span @click="goto('/find')">发现音乐页面</span>
<span @click="goto('/my')">我的音乐页面</span>
<span @click="goto('/part')">我的朋友页面</span>
</div>
<div class="top">
<router-view></router-view>
</div>
</div>
</template>
<script>
export default {
methods:{
goto(path){
// this.$route 路由参数对象,用于获取传递过来的参数
// this.$router 路由对象,进行路由跳转
this.$router.push({
path
})
// 简写--可以直接传字符串
//this.$router.push('/find')
// this.$$router.push(path)
}
}
};
</script>
第二种根据name来跳转
const routes=[
{
path:'/find',
component:Find,
name:'Find'
},
{
path:'/my',
component:My,
name:'My'
},
{
path:'/part',
component: Part,
name:'Part'
},
============================在路由配置name属性
<template>
<div>
<div class="footer_wrap">
<!--声明式导航 -->
<!-- <router-link to="/find">发现音乐</router-link>
<router-link to="/my">我的音乐</router-link>
<router-link to="/part">朋友</router-link> -->
<!-- 编程式导航跳转--根据路径跳转 -->
<span @click="goto('Find')">发现音乐页面</span>
<span @click="goto('My')">我的音乐页面</span>
<span @click="goto('Part')">我的朋友页面</span>
</div>
<div class="top">
<router-view></router-view>
</div>
</div>
</template>
<script>
export default {
methods:{
goto(name){
// this.$route 路由参数对象,用于获取传递过来的参数
// this.$router 路由对象,进行路由跳转
this.$router.push({
name
})
}
}
};
</script>
编程式导航传参两种方式无需任何配置
- 注意点1:如果用的是path路径跳转,则不能params来传,因为path会忽略params
- 所以如果用的是path来跳转的,则只能用query来传参
- 注意点2:如果比较隐私的数据用query建议不用query传,因为query在路径上
组合:
path+query传参
name+params 页面刷新后数据会丢失,但是不用担心丢失问题,因为传过去我们已经用了
<template>
<div>
<div class="footer_wrap">
<!--声明式导航 -->
<!-- <router-link to="/find">发现音乐</router-link>
<router-link to="/my">我的音乐</router-link>
<router-link to="/part">朋友</router-link> -->
<!-- 编程式导航跳转--根据路径跳转 -->
<span @click="goto">发现音乐页面</span>
<span @click="gotoQuery">我的音乐页面</span>
<span @click="gotoParams">我的朋友页面</span>
</div>
<div class="top">
<router-view></router-view>
</div>
</div>
</template>
<script>
/* 注意点:如果用的是path路径跳转,则不能params来传,因为path会忽略params
所以如果用的是path来跳转的,则只能用query来传参。*/
/* 总结:组合:path+query传参
name+params 页面刷新后数据会丢失
*/
export default {
methods:{
gotoQuery(){
this.$router.push({
path:'/my',
query:{
name:'假如生活欺骗了你'
}
})
},
========================query传query接
<h1>我是my页面</h1>
<h1>{{$route.query.name}}</h1>
=====================================
gotoParams(){
this.$router.push({
name:'Part',
params:{
name:'不要悲伤,不要心急'
},
query:{
age:18
}
})
},
goto(){
}
}
}
</script>
======================params传params接
<h1>我是part页面</h1>
<h1>{{$route.query.age}}</h1>
<h1>{{$route.params.name}}</h1>
重定向和模式
什么是路由重定向(redirect)
就是匹配path后强制跳转path的路径
const routes = [
{
path: "/", // 默认hash值路径
redirect: "/find" // 重定向到/find
// 浏览器url中#后的路径被改变成/find-重新匹配数组规则
}
]
404页面(*)
- 请求一个不存在页面,我们可以显示404页面
- 可以新建一个组件做404页面,我们为给用户更好的体验,写样式,然后*号配置路由即可
import NotFound from '@/views/NotFound'
const routes = [
// ...省略了其他配置
// 404在最后(规则是从前往后逐个比较path)
{
path: "*",
component: NotFound
}
]
路由模式设置(*)
在实例化路由对象时,传入mode选项和值修改
const router = new VueRouter({
routes,
mode: "history" // 打包上线后需要后台支持, 模式是hash
})
嵌套和守卫
路由嵌children
const routes = [
// ...省略其他
{
path: "/find",
name: "Find",
component: Find,
children: [
{
path: "recommend",
component: Recommend
},
{
path: "ranking",
component: Ranking
},
{
path: "songlist",
component: SongList
}
]
}
// ...省略其他
]
14.Vue路由-声明式导航-类名区别
目标
目标: router-link自带的2个类名的区别是什么
- router-link-exact-active (精确匹配) url中hash值路径, 与href属性值完全相同, 设置此类名
- router-link-active (模糊匹配) url中hash值, 包含href属性值这个路径
15.Vue路由-全局前置守卫
什么是路由守卫(就是让路由有权限判断)
-
- 路由在真正跳转前, 会执行一次beforeEach函数, next调用则跳转, 也可以强制修改要跳转的路由
-
- 在路由对象上使用固定方法beforeEach 3:beforeEach他有三个参数
-
参数1 to: 要跳转到的路由 (路由对象信息) 目标
-
参数2 from: 从哪里跳转的路由 (路由对象信息) 来源
-
参数3 next,是否放行 (true,false)
-
注意一点:导航守卫一旦注册,必须使用next,否则路由系统就会瘫痪。
// 目标: 路由守卫
// 场景: 当你要对路由权限判断时
// 语法: router.beforeEach((to, from, next)=>{//路由跳转"之前"先执行这里, 决定是否跳转})
// 参数1 to: 要跳转到的路由 (路由对象信息) 目标
// 参数2 from: 从哪里跳转的路由 (路由对象信息) 来源
// 参数3 next: 函数体 - next()才会让路由正常的跳转切换, next(false)在原地停留, next("强制修改到另一个路由路径上") 决定是否放行
// 注意: 如果不调用next, 页面留在原地
// 例子: 判断用户是否登录, 是否决定去"我的音乐"/my
const isLogin = true; // 登录状态(未登录)
router.beforeEach((to, from, next) => {
if (to.path === "/my" && isLogin === false) {
alert("请登录")
next(false) // 阻止路由跳转
} else {
next() // 正常放行
}
})
总结: next()放行, next(false)留在原地不跳转路由, next(path路径)强制换成对应path路径跳转
16.Vue路由-组件缓存
组件缓存的好处:不会频繁创建和销毁组件,页面更快的呈现
1. <keep-alive></keep-alive>, 裹切换的挂载点即可
2:用法
<keep-alive>
<router-view></router-view>
</keep-alive>
2:
18.Vue路由-组件缓存-新钩子函数
- 1:上面介绍到了组件缓存,但是如果我只想缓存某个组件或者说我不想缓存某个组件怎么做
- 2:keep-alive的高级用法他有两个属性来解决上面的问题
- 第一步:给组件取个名字
<script>
export default {
name: '组件名'
}
</script>
- 第二步:包含缓存和不包含两种include/exclude
- include 只包含写入到include这个组件,一定要组件名,多个用逗号隔开
<keep-alive include="Find">
<router-view></router-view>
</keep-alive>
include 不包含写入到exclude这个组件,一定要组件名,多个用逗号隔开
<keep-alive exclude="My,Part">
<router-view></router-view>
</keep-alive>
19 组件路由钩子
- 前面学了8个路由钩子,现在扩展两个
- 使用keep-alive后, 新增了2个钩子函数
- 组件不执行销毁/初始化创建的方法了, 如何知道组件被失去激活/激活呢?
- activated --- 组件被激活状态
- deactivated --- 组件被失去激活状态
activated () {
console.log("发现音乐-组件激活");
},
deactivated () {
console.log("发现音乐-组件失去激活");
}