Vue知识点系列笔记:
Vue(一)基础 | 前端 | 课程笔记
Vuex | 前端 | 课程笔记
本章vue-router:b站课程链接 p117-p133
Vue-router思维导图
(由于图片文件太大无法上传,只能截图)
Ch1 Vue-router
1.1 相关理解
1.1.1 vue-router的理解
vue的一个插件库,专门用来实现SPA应用
1.1.2 对SPA应用的理解
- 单页Web应用(single page web application,SPA)
- 整个应用只有一个完整的页面
- 点击页面中的导航链接不会刷新页面,只会做页面的局部更新
- 数据需要通过ajax请求获取
1.1.3 路由的理解
- 什么是路由?
(1)一个路由就是一组映射关系(key-value)
(2)key为路径,value可能是function或component - 路由分类
(1)后端路由:
=>理解:value是function,用于处理客户端提交的请求
=>工作过程:服务器接收到一个请求时,根据请求路径找到匹配的函数处理请求,返回响应数据。
(2)前端路由:
=>理解:value是component,用于展示页面内容
=>工作过程:当浏览器的路径改变时,对应的组件就会显示
1.2 基本路由
操作步骤:
- 安装vue-router,命令:npm i vue-router
- 应用插件:Vue.use(VueRouter)
- 在router/index里编写router配置项:
//引入VueRouter
import VueRouter from 'vue-router'
//引入Luyou 组件
import About from '../components/About'
import Home from '../components/Home'
//创建router实例对象,去管理一组一组的路由规则
const router = new VueRouter({
routes:[
{
path:'/about',
component:About
},
{
path:'/home',
component:Home
}
]
})
//暴露router
export default router
- 实现切换(active-class可配置高亮样式)
<router-link active-class="active" to="/about">About</router-link>
- 指定展示位置
<router-view></router-view>
注意:
路由组件通常存放在pages文件夹,一般组件通常存放在components文件夹。
通过切换,“隐藏”了的路由组件,默认是被销毁掉的,需要的时候再去挂载。
每个组件都有自己的 r o u t e 属 性 , 里 面 存 储 着 自 己 的 路 由 信 息 。 整 个 应 用 只 有 一 个 r o u t e r , 可 以 通 过 组 件 的 route属性,里面存储着自己的路由信息。 整个应用只有一个router,可以通过组件的 route属性,里面存储着自己的路由信息。整个应用只有一个router,可以通过组件的router属性获取到。
1.3 嵌套路由(多级路由)
- 配置路由规则,使用children配置项:
routes:[
{
path:'/about',
component:About,
},
{
path:'/home',
component:Home,
children:[ //通过children配置子级路由
{
path:'news', //此处一定不要写:/news
component:News
},
{
path:'message',//此处一定不要写:/message
component:Message
}
]
}
]
- 跳转(要写完整路径):
<router-link to="/home/news">News</router-link>
- 指定展示位置
<router-view></router-view>
嵌套路由更多内容详见《Vue-router嵌套路由》
1.4 命名路由
为了方便的表示路由的路径, 可以给路由规则起一个别名, 即为"命名路由"
var router = new VueRouter({
routes: [
{
path: '/user/:id',
component: user_com,
// 命名路由
name: 'user',
props: true,
},
],
});
<router-link :to="{name: 'user', params: {id: 123}}">User3</router-link>
router.push({
name: 'user',
params: {
id: 123
},
});
1.5 路由重定向
路由重定向详见《路由重定向和别名》
1.6 路由的query参数
- 传递参数
query的两种写法:
(1)to的字符串写法
//Message.vue
<ul>
<li v-for="m in messageList" :key="m.id">
<!-- 跳转路由并携带query参数,to的字符串写法 -->
<router-link :to="`/home/message/detail?id=${m.id}&title=${m.title}`">{
{
m.titel}}<router-link>
</li>
</ul>
(2)to的对象写法
<ul>
<li v-for="m in messageList" :key="m.id">
<!-- 跳转路由并携带query参数,to的对象写法 -->
<router-link :to="{
path:'/home/message/detail',
query:{
id: m.id,
title: m.title
}">
{
{
m.title}}
<router-link>
</li>
</ul>
- 接受参数:
$route.query.id
$route.query.title
- router配置
routes:[
{
path:'/home',
component:Home,
children:[
{
path:'news',
component:News,
},
{
path:'message',
component:Message,
children:[
{
path:'detail',
component:Detail,
}
]
}
]
}
]
})
1.7 命名路由
作用: 可以简化路由的跳转
操作步骤:
- 给路由命名
{
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>
<!-- 简化写法配合传递参数 -->
<ul>
<li v-for="m in messageList" :key="m.id">
<router-link
:to="{
name:'hello',
query:{
id:m.id,
title:m.title
}
}">
{
{
m.title}}
</router-link>
</li>
</ul>
1.8 路由的params参数
- 配置路由,声明接受params参数
{
path:'/home',
component:Home,
children:[
{
path:'news',
componnet:News
},
{
component:Message,
children:[
{
name:'xiangqing',
path:'detail/:id/:title',//使用占位符声明接受params参数
component:Detail
}
]
}
]
}
- 传递参数
params的两种写法
字符串写法:
<!-- 跳转并携带params参数,to的字符串写法-->
<ul>
<li>
<router-link :to="/home/message/detail/">跳转</router-link>
对象写法:
<!-- 跳转并携带params参数,to的对象写法-->
<ul>
<li>
<router-link
:to="{
name:'xiangqing',
params:{
id: ,
title: ,
}
}">
跳转
</router-link>
</li>
</ul>
特别注意:
路由携带params参数时,若使用to的对象写法,则不能使用path配置项,必须使用name配置。
- 接受参数:
$route.params.id
$route.params.title
1.9 路由的props配置
作用:让路由组件更方便的收参数
//router/index.js
{
name:'xiangqing',
path:'detail/:id',
component:Detail,
//第一种写法,props值为对象,该对象中所有的key-value的组合最终都会通过props传给Detail组件
//props:{a:900}
//第二种写法:props值为布尔值,布尔值为true,则把路由受到的所有prams参数通过props穿给Detail组件
//props:true
//第三种写法:props值为函数,该函数返回的对象中每一组key-value都会通过props传给Detail组件
props(route){
return {
id:route.query.id,
title:route.query.title
}
}
}
//props({query}){
//return {
//id:query.id,
//title:query.title
//}
//}
//}
//Detail.vue
<template>
<ul>
<li>消息编号:{
{
id}}</li>
<li>消息标题:{
{
title}}</li>
</ul>
</template>
<script>
export default {
name:'Detail',
props:['id','title']
}
</script>
1.10 router-link的replace属性
- 作用:控制路由跳转时操作浏览器历史记录的模式
- 浏览器的历史记录有两种写入方式:分别为push和replace,push是追加历史记录,replace是替换当前记录。路由跳转时默认为push
- 如何开启replace模式:
<router-link replace ...>News</router-link>
1.11 编程式路由导航
作用:不借助router-link实现路由跳转,让路由跳转更灵活
<template>
<div class="col-xs-offset-2 col-xs-8">
<div class="page-header">
<h2>Vue Router Demo</h2>
<button @click="back">后退</button>
<button @click="forward"></button>
</div>
</div>
</template>
<script>
export default {
name:'Banner',
methods:{
back(){
this.$router.back()
},
forward(){
this.$router.forward()
},
},
}
</script>
1.12 缓存路由组件
作用:让不展示的路由组件保持挂载,不被销毁
<keep-alive include="News">
<router-view></router-view>
</keep-alive>
1.13 两个新的生命周期钩子
- 作用:路由组件所独有的两个钩子,用于捕获路由组件的激活状态。
- 具体名称:
activated 路由组件被激活时触发
deactivated 路由组件失活时触发
<script>
export default {
name:'News',
data(){
return {
opacity:1
}
},
activated(){
console.log('News组件被激活了')
this.timer = setInterval(() => {
console.log('@')
this.opacity -=0.01
if(this.opacity <= 0) this.opacity = 1
},16)
},
deactivated(){
console.log('News组件失活了')
clearInterval(this.timer)
},
}
</script>
1.14 路由守卫
1.13.1全局前置-路由守卫
全局前置路由守卫什么时候被调用?
(1)初始化时被调用;
(2)每次路由切换之前调用
//router/index.js
router.beforeEach((to,from,next)=>{
console.log(to,from)
if(to.name === 'xinwen' || to.name == 'xiaoxi'){
if(localStorage.getItem('school') === 'atguigu')}
next()
}else{
alert('学校名不对,无权限查看')
}
}else{
next()
}
})
1.14.2 全局后置-路由守卫
全局后置路由守卫什么时候被调用?
(1)初始化时
(2)每次路由切换之后
//router/index.js
router.afterEach((to,from)=>{
console.log('后置路由守卫',to,from)
document.title = to.meta.title || '硅谷系统'
})
1.14.3 独享守卫
//router/index.js
routes= {
name:'xinwen',
path:'news',
component:News,
meta:{
isAuth:true,title:'新闻'},
beforeEnter: (to,from.next) => {
console.log('前置路由守卫',to,from)
if(to.meta.isAuth){
//判断是否需要鉴权
if(localStorage.getItem('school') === 'atguigu'){
next()
}else{
alert('学校名不对,无权限查看')
}
}else{
next()
}
},
//afterEnter(){
//}
1.14.4 组件内守卫
<script>
export default {
name:'About',
mounted(){
//console.log('%%%',this.$route)
},
//通过路由规则鹅,进入该组件时被调用
beforeRouteEnter(to,from,next){
console.log('About--beforeRouteEnter',to,from)
if(to.meta.isAuth){
//判断是否需要鉴权
if(localStorage.getItem('school')==='atguigu'){
next()
}else{
alert('学校名不对,无权限查看')
}
}else{
next()
}
},
//通过路由规则,离开该组件时被调用
beforeRouteLeave(to,from,next){
console.log('About--beforeRouteLeave',to,from)
}
}
1.14.5 路由守卫总结
- 作用:对路由进行权限控制
- 分类:全局守卫、独享守卫、组件内守卫
- 全局守卫:
//全局前置守卫,初始化时执行、每次路由切换前执行
router.beforeEach((to,from,next) => {
console.log('before',to,from)
if(to.meta.isAuth){
//判断当前路由是否需要进行权限控制
if(localStorage.getItem('school') === 'atguigu'){
//权限控制的具体规则
next() //放行
}else{
alert('暂无权限查看')
}
}else{
next()//放行
}
})
//全局后置守卫,初始化时执行、每次路由切换后执行
router.afterEach((to,from)=> {
console.log('afterEach',to,from)
if(to.meta.title){
document.title = to.mata.title //修改网页的title
}else{
document.title = 'vue_test'
}
})
- 独享守卫
beforeEnter: (to,from.next) => {
console.log('前置路由守卫',to,from)
if(to.meta.isAuth){
//判断是否需要鉴权
if(localStorage.getItem('school') === 'atguigu'){
next()
}else{
alert('学校名不对,无权限查看')
}
}else{
next()
}
}
- 组件内守卫
//进入守卫,通过路由规则,进入该组件时被调用
beforeRouterEnter(to,from,next){
},
//离开守卫,通过路由规则,离开该组件时被调用
beforeRouteLeave(to,from,next){
}
1.15 路由器的两种工作模式
- 对于一个url来说,什么是hash值?
#及其后面的内容就是hash值 - hash值不会包含在HTTP请求中,即hash值不会带给服务器
- hash模式:
(1)地址中永远带#号,不美观;
(2)看以后将地址通过第三方手机app分享,若app校验严格,则地址会被标记为不合法;
(3)兼容性较好; - history模式:
(1)地址干净,美观;
(2)兼容性和hash值相比略差;
(3)应用部署上线时需要后端人员支持,解决刷新页面服务端404的问题;
Vue-router知识点补充:前端路由vue-router