Vue-router知识点总结
文章目录
vue-router是一个插件库,专门用来实现SPA应用
一、SPA应用
- 单页web应用
(single page web application) - 整个应用只有一个完整的页面
- 点击页面中的导航链接不会刷新页面,只会做页面的局部更新
- 数据需要通过ajax请求获取
二、路由
1. 什么是路由?
- 路由就是一组映射关系(key-value)
- key为路径,value可能是function或component
2. 路由分类
- 后端路由:value是function,用于处理客户端提交的请求
工作过程:服务器收到一个请求时,根据请求路径找到匹配的函数来处理请求,返回响应数据
- 前端路由:value是component,用于页面展示
工作过程:当浏览器的路径改变时,对应的组件就会显示
三、基本使用
- 安装
vue-router4只能在vue3中使用
vue-router3可以在vue2中使用
npm i vue-router@3
- 应用插件
Vue.use(VueRouter)
- 编写router配置项
- 提前写好两个组件,MyAbout,MyHome,
- 创建
router/index.js
//该文件专门用于创建整个应用的路由器
import VueRouter from 'vue-router'
//引入组件
import MyAbout from '../pages/MyAbout.vue'
import MyHome from '../pages/MyHome.vue'
//创建一个路由器
export default new VueRouter({
routes: [{
path: '/about',
component: MyAbout
},
{
path: '/home',
component: MyHome
}
]
})
- 实现切换:
原先使用a标签,vue中使用router-link
<router-link class="list-group-item" active-class="active" to="/home">Home</router-link>
- 指定展示位置
<router-view>我是默认内容</router-view>
- 注意点
- 路由组件通常存放在pages文件夹,一般组件通常存放在components文件夹
- 通过切换,“隐藏”了的路由组件,默认是被销毁的,需要时的时候再去挂载
- 每个组件都有自己的
$route属性,里面存储着自己的路由信息 - 整个应用只有一个
router,可以通过组建的$router属性获取到
四、多级(嵌套)路由
- 配置路由规则,使用
children配置项,children里面的path就不要再写最前面的斜杠/了
//该文件专门用于创建整个应用的路由器
import VueRouter from 'vue-router'
//引入组件
import MyAbout from '../pages/MyAbout.vue'
import MyHome from '../pages/MyHome.vue'
import MyNews from '../pages/MyNews.vue'
import MyMessage from '../pages/MyMessage.vue'
//创建一个路由器
export default new VueRouter({
routes: [{
path: '/about',
component: MyAbout
},
{
path: '/home',
component: MyHome,
//子路由
children:[
{
path:'news',
component:MyNews
},
{
path:'message',
component:MyMessage
}
]
},
]
})
- 跳转(要写完整路径,加上自己的上一级路径):
<router-link to="/home/news" class="list-group-item>news</router-link>
五、路由的query参数
1. to的字符串写法
<router-link :to="`/home/message/detail?id=${m.id}&title=${m.title}`">{{m.title}}</router-link>
2. to的对象写法
<router-link
:to="{
path: '/home/message/detail',
query: {
id: m.id,
title: m.title,
},
}"
></router-link>
3. 接收参数
<li>消息编号:{{$route.query.id}}</li>
<li>消息标题:{{$route.query.title}}</li>
六、路由命名
1. 作用
简化路由的跳转
2. 给路由命名
{
path: '/home',
component: MyHome,
//子路由
children: [
{
name:'message',
path: 'message',
component: MyMessage,
children: [
{
//路由命名
name:'xiangqing',
path: 'detail',
component: MyDetail
}
]
}
]
}
3. 简化跳转
//原先
<!-- <router-link to="/home/message/detail">{{m.title}}</router-link> -->
// 简化后
<!-- <router-link :to="{name:"xiangqing"}">{{m.title}}</router-link> -->
// 简化写法配合传递参数
<router-link
:to="{
name: 'xiangqing',
query: {
id: m.id,
title: m.title,
},
}"
>{{ m.title }}
</router-link>
七、路由的params参数
- 在配置路由规则的
index.js文件里,在path项中添加占位符
children: [
// params参数
{
//路由命名
name: 'xiangqing',
path: 'detail/:id/:title',//使用占位符声明params参数
component: MyDetail
}
]
- 使用
- 注意:对象写法中不可以写
path项,只能使用name
// 路由携带params参数,to的字符串写法
<router-link :to="`/home/message/detail/${m.id}/${m.title}`">{{m.title}}</router-link>
//路由携带params参数,to的对象写法
<router-link
:to="{
name: 'xiangqing',
params: {
id: m.id,
title: m.title,
},
}"
>{{ m.title }}
</router-link>
- 接收参数
<li>消息标题:{{$route.params.title}}</li>
八、路由的props配置
- 第一种写法:
值为对象,对象中的所有key-value都会以props形式传递给Detail组件
props:{
a:1,b:'2'
}
接收并使用:
<template>
<li>a:{{a}}</li>
<li>b:{{b}}</li>
</template>
<script>
props:['a','b']
</script>
- 第二种写法:
值为布尔值,若布尔值为真,就会把该路由组件收到的所有params参数以props形式传递给Detail组件
path: 'detail/:id/:title',
props:true
接受并使用:
<template>
<li>消息编号:{{ id }}</li>
<li>消息标题:{{ title }}</li>
</template>
<script>
props: ["id", "title"],
</script>
- 第三种写法(最强大):
值为函数
props($route)
{
return { id: $route.query.id, title: $route.query.title }
}
// 或者使用解构赋值写法
props({query})
{
return { id: query.id, title: query.title }
}
接受并使用:
<template>
<li>消息编号:{{ id }}</li>
<li>消息标题:{{ title }}</li>
</template>
<script>
props: ["id", "title"],
</script>
九、<router-link>的replace属性
- 作用:控制路由跳转时操作浏览器历史纪录的模式
也就是浏览器的这个地方,控制上一页和下一页

- 浏览器的历史纪录有两种写入方式,分别为
push和replace,push是追加历史记录,replace是替换掉当前的历史记录,默认为push,想要切换成replace,则:
<router-link replace .....></router-link>
栈模式,指针指向顶部,点击回退按钮,指针向下移,点击享有的按钮,指针上移

十、编程式路由导航
- 作用:不借助
<router-link></router-link>,让路由跳转更加灵活 - $router的五个API
this.$router.push({
name: "xiangqing",
query: {
id: m.id,
title: m.title,
},
});
this.$router.replace({
name: "xiangqing",
query: {
id: m.id,
title: m.title,
},
});
//回到上一页
this.$router.back();
//前进一页
this.$router.forward();
//传递数字,证书表示前进,负数表示回退
this.$router.go(3);
十一、缓存路由组件
- 问题:
在切换组件的时候,呗“隐藏”的组件其实是被销毁了,再次切换回来的时候是重新挂载的,但是如果组件中有输入框,被切换走后在切换回来,用户输入的内容就会被清空,为了解决这一问题,可以使用缓存路由
- 想要缓存哪一个组件里的内容,就在他所在的组件中(可以说是他的父组件)操作
- 使用
<keep-alive>标签
<keep-alive>
<router-view></router-view>
</keep-alive>
- 加上
include="组建的名字name"标签,可以指定缓存哪个组件里的内容,如果不写,则默认缓存全部组件
<keep-alive include="MyNews">
<router-view></router-view>
</keep-alive>
- 作用:让不展示的组件保持挂载,不被销毁
十二、两个新的生命周期钩子
- 引出问题:切换组件,隐藏的组件被销毁,显示的组件被挂载,如果我们希望缓存组件中的数据,就会使用
<keep-alive>来让组件保持挂载,不被销毁。但如果组件中有定时器,我们希望在不展示的时候将他清除,但因为使用了路由缓存,没法在调用beforeDestroy()钩子来清除定时器,所以我们引出下面两个路由组件中独有的两个钩子:activated()和deactivated() - 两个钩子的作用:用于捕获路由组件的激活
activated()和失活deactivated()状态 - 示例
<template>
<div>
<ul>
<li class="change" :style="{ opacity }">我的样式要变化</li>
</ul>
</div>
</template>
<script>
export default {
name: "MyNews",
data() {
return {
opacity: 1,
};
},
// beforeDestroy(){
// console.log("news被销毁了");
// clearInterval(this.timer);
// },
// mounted(){
// this.timer=setInterval(()=>{
// this.opactiy-=0.1;
// if(this.opacity<=0){
// this.opacity=1;
// }
// })
// },
//路由组件独有的两个生命周期钩子
//激活
activated() {
console.log("news被激活了");
this.timer = setInterval(() => {
console.log(this.opacity)
this.opacity -= 0.1;
if (this.opacity <= 0) {
this.opacity = 1;
}
},16);
},
//失活
deactivated() {
console.log("news被失活了");
clearInterval(this.timer);
},
};
</script>
十三、路由守卫
引出问题:有的时候查看东西需要权限,比如要登陆,或者身份必须得是管理员才能查看等,这时候就需要路由守卫
1. 全局路由守卫
- 全局前置路由守卫
初始化的时候执行,每次路由切换之前被调用
router.beforeEach((to, from, next) => {
//to表示要去往的,from表示从哪来
console.log(to, from)
if (to.meta.isAuth) {//判断是否需要授权
//只有当学校的名字十hky时才会放行,切换路由
if (localStorage.getItem('school') === 'hky') {
next();
} else {
alert('学校名不对,无权限访问')
}
} else {
//如果不需要授权,直接放行
next()
}
})
要给自己配制的路由规则中添加meta项,表示如果要切换到该路径,需要授权
meta: { isAuth: true},
- 全局后置路由守卫
初始化时执行,每次路由切换后执行
router.afterEach((to, from) => {
console.log("ddddd", to, from)
if (to.meta.title) {
document.title = to.meta.title
} else {
document.title = 'route_test'
}
})
更改的是这个地方的title

2. 独享守卫beforeEnter
在配置路由规则的时候写,只有前置,没有后置
meta: { isAuth: true, title: '新闻' },
beforeEnter(to, from, next) {
console.log("beforeEnter被调用")
if (to.meta.isAuth) {//判断是否需要授权
//只有当学校的名字十hky时才会放行,切换路由
if (localStorage.getItem('school') === 'hky') {
next();
} else {
alert('学校名不对,无权限访问')
}
} else {
//如果不需要授权,直接放行
next()
}
}
3. 组件内守卫
//进入守卫,通过路由规则,进入该组件时被调用
beforeRouteEnter(to,from,next){},
//离开守卫,通过路由规则,离开该组件时被调用(不常用)
//但要注意,如果还想实现切换到某一路径后,标签页的名字跟着一起更改,就不可以把逻辑写在这里,
//应该写在全局后置守卫中
beforeRouteLeave(to,from,next){}
十四、路由器的两种工作模式
- 对于一个url来说,什么是hash指?
#及其后面的内容就是hash指
- hash指不会包含在http请求中,不会带给服务器
- hash模式:
- 地址中永远带着#号,不美观
- 若以后将地址通过第三方手机app分享,若app校验严格,则地址会被标记为不合法
- 兼容发行较好
- history模式
- 地址干净,美观
- 兼容性和hash模式相比略差
- 应用部署上线时需要后端人员支持,解决刷新页面服务端404问题
生活感悟
这周进度比较快,看视频看的也比较仔细,只是有时候犯懒看视频的时候不想记笔记,导致今天写博客总结的时候发现有好几节内容只写了个标题,代码也不知道写哪去了,我又只得回去再看一遍视频,以后学习一定不能这样,还是得多敲。
引用舍友朋友圈的一句话:学计算机的,代码跑不动,我也跑不动
求代跑(无偿)
学习计划
这一阶段的学习计划就剩10天了,这周把TS学完,复习一下Vue,另外Python也得好好学学,下周好像要考试。还有时间的话把js高级也得复习一下,忘完了快
更多推荐


所有评论(0)