之前已经了解了VUE中路由的原理和使用,现在来解锁更多的路由使用方式

动态路由

动态路由的意思就是用同一个组件接受不同的信息来展示不同的内容

1
2
3
4
5
<li v-for="item in hotmodel" :key="item.productId">
<router-link :to="'/wap/product/'+item.productId">
<h3>{{item.title}}</h3>
</router-link>
</li>
1
2
3
4
5
{
path: '/wap/product/:id',
name: 'product',
component: () => import('../views/Product.vue')
}

在子组件内可以通过$route.params.id来获取这个参数

嵌套路由

路由中还可以增加子路由,格式如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
path:"/course",
name:"course",
component:()=>import("../views/Course.vue"),
children:[
{
path:"java",
component:()=>import("../components/Java.vue")
},
{
path:"python",
component:()=>import("../components/Python.vue")
}
]
}

编程式导航

路由的导航可以不用router-link,而是用js来路由

1
<button @click="fn">跳转到java页面</button>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
methods:{
fn(){
// push得到的新页面允许后退到当前页面
this.$router.push('/course/java')
// replace替换页面,不可后退到当前页面
// this.$router.replace('/course/java')
// 页面后退
// this.$router.back()
// 页面前进
// this.$router.foward()
// go方式
// 前进两个页面
// this.$router.go(2)
// 后退三个页面
// this.$router.go(-3)
// 根据名字跳转 (就是写在js里面的名字)
// this.$router.push({name:"java"})
}
}

参数传递

1
2
3
4
5
<!-- 通过params传递参数 -->
<button @click="$router.push({name:'java',params{id:'123'}})"></button>

<!-- 通过query传递参数: 地址会多出?search=搜索内容 -->
<button @click="$router.push({name:'java',query{search:'搜索内容'}})"></button>

命名视图

用于同级展示多个视图,每个视图用一个组件来渲染

1
2
3
<router-view class="view one" name="header" />
<router-view class="view menu" />
<router-view class="view three" name="content" />
1
2
3
4
5
6
7
8
9
{
path:'/news',
name:'news',
components:{
defaults:()=>import(../components/Menu.vue),
header:()=>import(../components/Newsheader.vue)
content:()=>import(../components/Newscontent.vue)
}
}

其中如果router-view没有name属性,则默认为default,特别注意上述js代码中是components

重定向与别名

重定向的意思就是,用户访问/a的时候,URL会被替换为/b,匹配路由为/b,就比如你的导航页面被劫持了,打开浏览器的首页被重定向到了一个奇奇怪怪的导航页面,而别名的意思就是URL没有替换,但是同样都可以访问到/a,就是URL是/b的时候,显示的也是/a的页面内容

以下是三种重定向(redirect)方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 根据后缀地址重定向
{
path: "/course",
name: "course",
redirect: "/course/java"
}

// 根据页面名重定向
{
path: "/course",
name: "course",
redirect: {name:"java"}
}

// 用函数重定向
{
path:"/user",
name: "user",
redirect:()=>`/user/${localStorage.userType}`
}

别名(alias)的使用方法如下

1
2
3
4
5
{
path:"/user",
name: "user",
alias:'/b',
}

路由传参解耦

我们可以在router/main.js中配置props,在组件中引入props然后使用

1
2
3
4
5
6
7
8
{
path:'vip',
name:'vip',
component:() =>import('../components/Vip.vue'),
props:{
description:"当前的数据是vip用户的数据"
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!-- vip组件 -->
<template>
<div>
<h1>VIP组件</h1>
<p>{{description}}</p>
</div>
</template>
<script>
export default {
props: ['description'],
mounted () {
console.log(this)
}
}
</script>

路由守卫

全局前置守卫

直接写在router/index.js中,用于控制全部的路由

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 每次路由跳转会进入该函数
router.beforeEach((to, from, next)=>{
console.log("当前页面是", from)
console.log("即将访问的页面是", to)
// 当执行了next()之后才能显示出路由跳转的页面
// next()
if(to.name=="admin"){
if(localStorage.isLogin=="true"){
next()
}else{
// 跳转到login页面
next('/login')
}
}
next()
})

全局后置守卫

类似前置守卫

1
2
3
router.afterEach((to,from)=>{

})

路由单独守卫

写在每个路由里面

1
2
3
4
5
6
7
{
path: '/foo',
component: Foo,
beforeEnter: (to, from, next) => {
// ...
}
}

组件守卫

组件守卫就是组件内部的方法

1
2
3
4
5
6
7
8
9
10
11
12
// 在路由跳转时,如果会访问到当前组件,则会触发该守卫
beforeRouteEnter(to, from, next) {
next(confirm('Enter Home?'));
},
// 在路由跳转时,如果离开当前组件,则会触发该守卫
beforeRouteLeave (to, from, next) {
next(confirm('Leave Home?'));
},
// 在当前路径下,当路由的参数发生变化时,才会触发该路由守卫
beforeRouteUpdate(to, from, next) {
console.log(to.params.path);
}

路由元信息

路由元信息meta可以自由配置,配置方式如下

1
2
3
// router/main.js
components:{}=>import(),
meta:{requestAuth:true}

可以利用路由元信息在beforeEach里判断meta.requestAuth而不用对每个页面特判