Vue的router详解
vue-router参数配置,vue-router的相对路径和绝对路径,带/和不带/的区别,vue-router路由的嵌套使用,vue-router的路由传参,keep-alive的使用,vue-router动态添加路由,删除路由,vue-router导航守卫的使用
目录
一、Vue-Router作用
个人理解:
就是拼接完整的URL,负责了端口号之后的路径[参数]
这部分。
URL:
http://<host>:<port>/<path>?<searchpart>
二、路由配置及使用
1、配置参数
“path”
用于配置访问路径
“name”
用于给该路由命名
“component”
表示需要映射的组件
“redirect”
表示重定向
“children”
用于路由嵌套
2、默认路径(相对路径和绝对路径)
const routes = [
{
path: '/',
redirect: '/root',
},
{
path: '/root',
name: 'root',
component: Root,
},
]
注意
(1)path: '/'
配置的是根路径:/
。反映到URL上就是/<path>
的/
部分。
(2)redirect: '/root'
,是指将根路径(/)
重定向到根路径下的root路径下(/root)
(3)path: '/root',
需要带“/”
,表示根路径下的root路径下(/root)
(1)带“/”和不带“/”的区别
带
/
,表示绝对路径
,/
是根路径,表示的是/<path>
的/
部分。
不带/
,表示相对路径
,相对于父路由下的路径(如果没有则找到根路径)
注意:
一般是在path
或redirect
里可能用到“/”
。
父路由
如何判断方式?
从当前相对路径的代码行(path、redirect都可以)开始,往上找一个包裹他的路由就是父路由
3、路由嵌套(路由重定向)
const routes = [
{
path: '/',
redirect: '/root',
},
{
path: '/root',
name: 'root',
component: Root,
redirect: '/root/child1',
children: [
// { // 等效于 外层的 redirect: '/root/child1',
// path:'',
// redirect:'child1'
// },
{
path: 'child1', // 等效于'/root/child1'
name: 'child1',
component: child1,
redirect: '/root/child1/child3',
children:[
{
path: 'child3', // 等效于'/root/child1/child3'
name: 'child3',
component: child3,
}
]
}
]
}
]
redirect: '/root/child1',
表示重定向到根路径下的root下的child路径
注意
(1)如果写成redirect: 'root/child1'
,也可以到http://192.168.1.8:8080/root/child1
,是因为root
的相对路径本就是根路径/
,所以没问题
(2)如果写成redirect: '/child1'
,路径会到http://192.168.1.8:8080/child1
,因为'/child1'
的意思是根路径下的child1路径
(3)如果写成redirect: 'child1'
,等效于redirect: '/child1'
(4)等效于children里的{ path:'', redirect:'child1' }
第一个children
下的配置
注意
path: 'child1'
,不需要写“/”
,
不写“/”
代表相对路径
,先找他的父组件/root
,最终等效于/root/child1
写了“/”
代表绝对路径
,直接匹配/child1
children
的多层嵌套(第二个children下的配置)
注意
redirect: '/root/child1/child3'
等效于redirect: 'child1/child3'
,都是指向/root/child1/child3
还是相对路径和绝对路径的问题,不过第一种写法更利于阅读
4、动态路由匹配
参数获取
一个
“路径参数”
使用冒号:
标记。
通过this.$route.params.[id]
获取路径中的变量,[id]
只跟在routes
里定义的变量名有关
在vue文件中需要写成this.$router.push('/user/kobe/id/111')
5、路由传参
(1)vue文件中传参
注意:
(1)通过query
传参,既可以写path
,也可以写name
。通过this.$route.query.id
获取参数
(2)通过params
不能写path
,只能写name + params
。通过this.$route.params.id
获取参数
//子路由配置
{
path: '/child1,
name: 'child1',
component: child1
}
//父路由编程式传参(一般通过事件触发)
root1 () {
// query传参
this.$router.push({ path: '/child1', query: { id: '123' } }) // /child1?id=123
this.$router.push({ name: 'child1', query: { id: '456' } }) // /child1?id=456
// params传参
this.$router.push({ name: 'child1', params: { id: '789' } })
}
(2)routes里传参
注意:
(1)redirect
重定向可以使String
类型,也可以是Object
类型,Object
类型可以携带参数
(2)不能在路由对象中单独添加query
和params
属性,没有这两个属性,参考下例的root路由
const routes = [
{
path: '/',
// redirect: '/root', // 无参数情况
// query传参
redirect: {path:'/root', query:{ id: '123' }}, // /root?id=123
// redirect: {name:'root', query:{ id: '456' }}, // /root?id=456
// params传参
// redirect: {name:'root', params:{ id: '789' }},
},
{
path: '/root',
name: 'root',
component: Root,
// query:{ 错误写法
// id: '123'
// }
},
]
6、 keep-alive使用
作用
可以使被包含的组件保留状态(数据保存),避免组件频繁的被创建和销毁
它们有两个非常重要的属性:
include - 字符串或正则表达,只有匹配的组件会被缓存
exclude - 字符串或正则表达式,任何匹配的组件都不会被缓存
使用
keep-alive包裹router-view时,对应所有路径的组件都会被缓存
<keep-alive exclude="Profile,User"> // Profile,User这两个组件不缓存,中间不要加空格
<router-view></router-view>
</keep-alive>
场景(保存页面离开时的数据)
7、路由的懒加载
// 路由的懒加载
const child1 = () => import(/* webpackChunkName: "child1" */ '../views/router-test/child1.vue')
const routes = [
{
path: '/child1',
name: 'child1',
component: child1,
}
]
注意
- 懒加载,其实是指
import( '../views/router-test/child1.vue')
/* webpackChunkName: "child1" */
是webpack
的魔法语句,是为了分包用的import
只能写字符串路径,不支持变量。例如a ='../views/router-test/child1.vue' ,路由component: () => import(a)
,这样会报错- 一定要用变量的时候,可以通过
字符串模板
来提供部分信息给webpack
;例如import(./path/${myFile})
, 这样编译时会编译所有./path
下的模块,但运行时确定myFile
的值才会加载,从而实现懒加载。
8、Not Found路径
三、动态添加路由
四、删除路由
五、导航守卫
to参数: Route对象, 即将跳转到的Route对象
from参数: Route对象, 从哪一个路由对象导航过来的
返回值问题:
1.false: 不进行导航
2.undefined或者不写返回值: 进行默认导航
3.字符串: 路径, 跳转到对应的路径中
4.对象: 类似于 router.push({path: “/login”, query: …})
六、刷新当前路由
方法1:<router-view :key='$route.fullPath'>
fullPath:可以识别当前页面路由的完整地址,当地址发生改变(包括参数改变)则重新渲染页面(例如动态路由参数的变化)
方法2:this.$router.go(0)
方法3:location.reload()
方法2和方法3,这两种都可以刷新当前页面的,缺点就是相当于按ctrl+F5 强制刷新那种,整个页面重新加载,会出现一个瞬间的空白页面,用户体验不好,所以不推荐使用。
七、新窗口打开路由页面
if (file.fileType === 'ofd') {
let newUrl = this.$router.resolve({
// path: `/openofdfile?ofdUrl=${fileUrl}` // 跳转的路由地址,用path: 'path地址'也可以
name: 'openofdfile',
query: {
ofdFile: JSON.stringify(file.fileUrl)
}
})
window.open(newUrl.href, '_blank')
}
八、BUG 处理
8.1 刷新当前路由出现白屏错误
// vue.config.js
const BASE_URL = process.env.NODE_ENV === 'production' ? './' : '/'
8.2 f5刷新保持当前菜单选择
created () {
// 刷新路由保持当前状态
this.activeIndex = this.$route.path
}
九、不同的路由加载相同的组件,进行页面的强制刷新
9.1 背景
正常情况:比如A路由'/path1'
加载组件cpn,B路由'/path2'
也是加载组件cpn,组件cpn的生命周期只会执行一次。
9.2 强制刷新的解决方案
<router-view :key="$route.query.key || Math.random()"></router-view>
在router-view
加个key
值,可以是random随机数,这样路由在跳转时,由于key值变化,会导致组件重新加载
更多推荐
所有评论(0)