Vue-Router
1 基本介绍
1.1 官方文档
https://router.vuejs.org/zh/
1.2 介绍
Vue Router 是 Vue.js 官方的路由管理器。它和 Vue.js 的核心深度集成,让构建单页面应用变得易如反掌。包含的功能有:
- 嵌套的路由/视图表
- 模块化的、基于组件的路由配置
- 路由参数、查询、通配符
- 基于 Vue.js 过渡系统的视图过渡效果
- 细粒度的导航控制
- 带有自动激活的 CSS class 的链接
- HTML5 历史模式或 hash 模式,在 IE9 中自动降级
- 自定义的滚动条行为
1.3 效果图
1.4 线上演示地址
http://vuerouter.myoli.xin
1.5 码云地址(欢迎Star)
https://gitee.com/hongjunyong/vue-router-demo
2 DEMO布局搭建
2.1 设置首页为登录页
步骤一、引入登录页面
import login from '@/pages/login'
步骤二、使用登录页
const router = new Router({
// 去掉地址栏上的#号
// mode: 'history',
// 选中时通过添加类名添加样式
linkActiveClass: 'router-active',
scrollBehavior,
routes: [
// 登录页
{
path: '/',
component: login
}
]
})
2.2 圣杯布局
步骤一、页面布局(main.vue) --> 知识点:router-view
main.vue代码如下
<template>
<div>
<!-- 头部 begin -->
<div class="header"></div>
<!-- 头部 end -->
<!-- 菜单 begin -->
<div class="sideMenu"></div>
<!-- 菜单 end -->
<!-- 内容 begin -->
<div class="content"></div>
<!-- 内容 end -->
<!-- 版权 begin -->
<div class="footer">版权 @qishon 2018</div>
<!-- 版权 end -->
</div>
</template>
步骤二、引入相关页面
import main from '@/pages/main'
步骤三、路由嵌套(index.router.js)
const router = new Router({
// 去掉地址栏上的#号
// mode: 'history',
// 选中时通过添加类名添加样式
linkActiveClass: 'router-active',
scrollBehavior,
routes: [
// 主内容
{
path: '/main',
component: main,
// 子路由嵌套
children: [
// 仪表盘
// 切记这里的路由路径没有/
{
path: 'dashboard',
component: dashboard
}
]
}
]
})
3 初级知识点
3.1 我的第一个路由
1 路由配置
const router = new Router({
// 去掉地址栏上的#号
// mode: 'history',
// 选中时通过添加类名添加样式
linkActiveClass: 'router-active',
scrollBehavior,
routes: [
// 主内容
{
path: '/main',
component: main,
// 子路由嵌套
children: [
// 第一个路由
{
path: 'first',
// 别名使用
alias: 'firstAlias',
component: first
}
]
}
]
})
2 点击标签,实现跳转(需要带上/main路径,布局才会被划分4个部分) --> 知识点:router-link、默认是a标签的形式
<router-link to="/main/first">我的第一个路由</router-link>
3.2 获取到路由name的值
1 路由配置
const router = new Router({
// 去掉地址栏上的#号
// mode: 'history',
// 选中时通过添加类名添加样式
linkActiveClass: 'router-active',
scrollBehavior,
routes: [
// 主内容
{
path: '/main',
component: main,
// 子路由嵌套
children: [
// 获取到路由name的值
{
path: 'name',
name: 'qishon',
component: name
}
]
}
]
})
2 使用$route.name获取到路由name的值
{{$route.name}}
3.3 地址栏传递参数
1 路由配置
const router = new Router({
// 去掉地址栏上的#号
// mode: 'history',
// 选中时通过添加类名添加样式
linkActiveClass: 'router-active',
scrollBehavior,
routes: [
{
path: '/main',
component: main,
// 子路由嵌套
children: [
// 地址栏传递参数
{
path: 'params/:id/:name',
component: params
}
]
}
]
})
2 router-link传递参数
<router-link to="/main/params/1314/qishon">地址栏传递参数</router-link>
3 使用$route.params.xx获取参数
id:{{$route.params.id}}
name:{{$route.params.name}}
3.4 地址栏传递参数(加入正则)
1 路由配置
const router = new Router({
// 去掉地址栏上的#号
// mode: 'history',
// 选中时通过添加类名添加样式
linkActiveClass: 'router-active',
scrollBehavior,
routes: [
// 主内容
{
path: '/main',
component: main,
// 子路由嵌套
children: [
// 地址栏传递参数
{
path: 'params/:id/:name',
component: params
},
// 地址栏传递参数(加入正则)
{
path: 'params2/:id(\\d+)/:name',
component: params2
}
]
}
]
})
2 路由使用
- 正确(id只能传入数字)
<router-link to="/main/params2/520/qs">地址栏传递参数(加入正则)</router-link>
- 错误(id不能传入字符串类型)
<router-link to="/main/params2/abc/qs">地址栏传递参数(加入正则)</router-link>
3.5 N个参数 地址栏上看不到参数
1 知识点:使用:to进行路由跳转(与之前的跳转方式不一样)、name对应的是路由的name、使用params进行传递参数
<router-link :to="{ name: 'paramsMultiple', params: { username: 'qishon', age: 1818 }}">N个参数 地址栏上看不到参数</router-link>
2 页面上参数接收 --> 知识点:$route.params
{{$route.params.username}}
{{$route.params.age}}
3.6 N个参数 地址栏上带参数 --> http://localhost:8080/#/main/paramsMultiple2?username=zz&age=22
1 知识点:path进行路径跳转、使用query参数传递
<router-link :to="{ path: '/main/paramsMultiple2', query: { username: 'zz', age: 22 }}">N个参数 地址栏上带参数</router-link><br/>
2 页面上参数接收 --> 知识点:$route.query(与上面接收方式有所区别)
{{$route.query.username}}
{{$route.query.age}}
3.7 重定向
1 路由配置
// 重定向
{
path: 'redirect/:id(\\d+)/:name',
redirect: '/main/params2/:id(\\d+)/:name'
}
2 路由使用
<router-link to="/main/redirect/22/qishon">重定向</router-link>
3.8 动态设置路由(push)
<button @click="goForward">动态设置路由(push)</button>
// 不带参数
goForward () {
this.$router.push('/main/forward')
}
// 带参数
this.$router.push({name:'/volume-detail', params: {
addressInfo: this.addressInfo
}})
3.9 后退 --> 知识点:go(-1)、push
<button @click="goBack">后退</button><br/>
goBack () {
window.history.length > 1
? this.$router.go(-1)
: this.$router.push('/main/dashboard')
}
3.10 利用路由别名alias跳转
1 路由配置
// 第一个路由
{
path: 'first',
// 别名使用
alias: 'firstAlias',
component: first
},
2 路由使用
<router-link to="/main/firstAlias">返回(利用路由别名alias跳转)</router-link><br/>
3.11 beforeRouteEnter(进入路由时触发)、beforeRouteLeave(离开路由时触发)
可以写到路由配置里,但是只能监听到进入时的事件,离开时没办法监听到,所以一般写到对应的页面里
beforeRouteEnter:(to, from, next)=>{
console.log("准备进入路由模板");
next();
},
beforeRouteLeave: (to, from, next) => {
console.log("准备离开路由模板");
next();
}
3.12 tag设置路由标签形式
router-link默认是a标签的形式
<router-link tag="div" to="/main/tag">tag</router-link>
3.13 404错误(要放到所有路由的后面)
{
path: '*',
component: error
}
3.14 去掉地址栏上的#号
mode: 'history'
3.15 选中时通过添加类名添加样式
linkActiveClass: 'router-active'
3.16 a标签与router-link跳转的区别
- router-link组件支持用户在具有路由功能的应用中 (点击) 导航。 通过 to 属性指定目标地址,默认渲染成带有正确链接的a标签,可以通过配置 tag 属性生成别的标签。另外,当目标路由成功激活时,链接元素自动设置一个表示激活的 CSS 类名;而a标签实现路由跳转没有表示激活的css类名。
router-link比起写死的 a href="/#/main/a" 会好一些,理由如下:
- 无论是 HTML5 history 模式还是 hash 模式,它的表现行为一致,所以,当你要切换路由模式,或者在 IE9 降级使用 hash 模式,无须作任何变动。
- 在 HTML5 history 模式下,router-link 会守卫点击事件,让浏览器不再重新加载页面。
- 当你在 HTML5 history 模式下使用 base 选项之后,所有的 to 属性都不需要写 (基路径) 了。
a标签路由跳转 及 参数传递(a标签传递参数要在href的前缀加上/#/)、取值跟router-link一样
<a href="/#/main/a/123/abc">a标签跳转路由</a><br>
<a href="/#/main/a2?id=123&name=abc">a标签跳转路由</a><br>
a标签可以跳转到外部连接,而router-link不能跳转到外部连接
<a href="http://www.baidu.com">a标签可以跳转外链</a><br>
<router-link to="http://www.baidu.com">router-link标签不能跳转外链</router-link><br>
4 课堂练习
this.$router.push 和 this.$router.replace的区别
[站外图片上传中...(image-244344-1619677286013)]
- router.replace和router.push唯一的不同就是,不会向history添加新记录,而是替换掉当前的history记录
4 中高级知识点
4.1 路由拆分
在index.router.js引入模块路由文件
import routerDemo from '@/router/routerDemo.router'
在index.router.js的routes里使用路由文件
...routerDemo
4.2 路由动画
知识点:transition、mode
<!-- mode="in-out" 先进入后退出 -->
<!-- mode="out-in" 先退出再进入 -->
<transition name="fade" mode="out-in">
<router-view></router-view>
</transition>
动画效果
/*
fade-enter:进入过渡的开始状态,元素被插入时生效,只应用一帧后立刻删除。
fade-enter-active:进入过渡的结束状态,元素被插入时就生效,在过渡过程完成后移除。
fade-leave:离开过渡的开始状态,元素被删除时触发,只应用一帧后立刻删除。
fade-leave-active:离开过渡的结束状态,元素被删除时生效,离开过渡完成后被删除。*/
.fade-enter {
/* 完全透明 */
opacity:0;
}
.fade-leave{
/* 完全不透明 */
opacity:1;
}
.fade-enter-active{
transition:opacity .2s;
}
.fade-leave-active{
opacity:0;
transition:opacity .2s;
}
4.3 路由懒加载(优点:避免应用初始化速度慢)
component: () => import('@/pages/router/11-import')
4.4 路由自定义参数
定义参数
{
path: 'import',
meta: {
title: '动态引入',
url: 'qishon.com'
},
// 懒加载
component: () => import('@/pages/router/11-import')
},
获取参数
{{$route.meta.url}}
4.5 keep-alive缓存(用处:缓存用户表单信息、分页等)
在meta上自定义属性,keepAlive用于判断页面是否需要缓存
{
path: 'keepAlive',
meta: {
keepAlive: true
},
component: () => import('@/pages/router/13-keep-alive')
},
<transition name="fade" mode="out-in">
<keep-alive>
<router-view v-if="$route.meta.keepAlive"></router-view>
</keep-alive>
</transition>
<transition name="fade" mode="out-in">
<router-view v-if="!$route.meta.keepAlive"></router-view>
</transition>
4.6 beforeRouteUpdate
beforeRouteUpdate (to, from, next) {
// 在当前路由改变,但是该组件被复用时调用
// 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
// 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
console.log('触发')
next()
}
4.7 beforeEach全局守卫(用处:设置标题)
/**
* 全局守卫
* to: 即将要进入的目标 路由对象
* from: 当前导航正要离开的路由
* next(): 进行管道中的下一个钩子
*/
router.beforeEach((to, form, next) => {
// 路由变化修改title
let routerTitle = to.meta.title || '路由demo演示'
window.document.title = routerTitle
next()
})
4.8 scrollBehavior滚动行为(类似于跳转锚点、记录滚动条滚动的位置)
1 在index.router.js里加入如下代码
/**
* 滚动行为
* @param to 要进入的目标路由对象,到哪里去
* @param from 离开的路由对象,哪里来
* @param savedPosition 会记录滚动条的坐标,点击前进/后退的时候记录值{x:?,y:?}
* @returns {*}
*/
const scrollBehavior = function (to, from, savedPosition) {
if (to.hash) {
return {selector: to.hash}
}
}
2 在routes引入
3 路由配置
<router-link :to="{path:'/scroll#anchor2'}">滚动行为</router-link>