路由守卫
路由守卫就是在进入页面之前做一层判断,如果没有守卫,可以直接进入页面,如果添加了守卫,则需要做页面跳转。
例如有3个组件,分别是登录组件、商品详情组件、购物车组件。当用户单击商品详情时,可以直接进入页面,当单击购物车组件时,需要判断是否登录,如果登录即可进入购物车组件,如果没有登录则需要先跳转到登录页面。
路由守卫分为全局路由守卫、组件内路由守卫和离开组件时守卫。
全局路由守卫
打开 main.js,在 main.js 中添加下述代码。
router.beforeEach((to,from,next)=>{
// to表示要去的新页面
// from表示旧页面
// next表示是否放行
next()
})
代码解析如下。
router.beforeEach 表示开启路由守卫。
next 参数表示是否放行,不管有没有进行守卫判断都需要放行,否则会整体拦截页面。 |
创建 mylogin、mydetail、mycart 组件,实现上述案例,代码如下。
HelloWorld 组件中的视图层代码如下。
<div class="hello">
<router-link to="/mydetail">商品详情</router-link>
<router-link to="/mycart">购物车</router-link>
</div>
路由匹配规则代码如下。
export default new Router({
routes: [
{
path: '/',
name: 'HelloWorld',
component: HelloWorld
},
{
path: '/mylogin',
name: 'mylogin',
component: mylogin
},
{
path: '/mydetail',
name: 'mydetail',
component: mydetail
},
{
path: '/mycart',
name: 'mycart',
component: mycart,
meta: {
needAuth: true
}
},
]
})
代码解析如下。
注意,进入购物车组件是需要进行路由判断的,所以购物车组件的匹配规则多了一个 meta 属性,meta 属性就是判断组件是否需要守卫的。
main.js 代码如下。
router.beforeEach((to, from, next) => {
// to 表示要去的新页面
// from 表示旧页面
// next 表示是否放行
var islogin = 0 // 0 表示未登录,1 表示已登录
if (to.meta.needAuth) {
if (islogin == 0) {
router.push({ name: 'mylogin' })
}
if (islogin == 1) {
next()
}
} else {
// 如果没有 meta.needAuth 则直接放行
next()
}
})
代码解析如下。
声明 islogin 变量,0 表示未登录,1 表示已登录。运行程序,当单击购物车组件时会直接跳转到登录组件,实现守卫效果。
组件内路由守卫
7.10.1 节演示的是全局路由守卫,接下来介绍组件内路由守卫,新建订单组件 order.vue,进入订单组件时守卫,代码如下。
HelloWorld 视图层代码如下。
<router-link to="/order">订单</router-link>
路由匹配规则如下。
{
path: '/order',
name: 'order',
component: order
}
组件内守卫不需要 meta 属性。 |
order.vue 代码如下。
<template>
<h1>订单组件</h1>
</template>
<script>
export default {
beforeRouteEnter: (to, from, next) => {
var islogin = 0; // 0 表示未登录,1 表示已登录
if (islogin == 0) {
// 跳转到购物车页面
// 不能使用 router 跳转,应该使用 next 跳转
next({ name: "mycart" });
} else {
next();
}
}
};
</script>
代码解析如下。
同样声明 islogin 变量,判断是否登录。注意,路由跳转需要用到 next() 方法跳转,不能使用 router.push() 方法进行跳转。
运行程序,单击订单组件,由于 islogin 的值是 0,表示没有登录,因此会直接跳转到登录组件。
离开组件时守卫
7.10.2 节演示的是进入组件时守卫,Vue 还提供了离开组件时守卫,例如从订单组件返回到 HelloWorld 组件,代码如下。
<template>
<h1>订单组件</h1>
</template>
<script>
export default {
// 进入组件时守卫
// 1. islogin 设置为 1,表示已登录,先进入组件
beforeRouteEnter: (to, from, next) => {
var islogin = 1;
if (islogin == 0) {
next({ name: "mycart" });
} else {
next();
}
},
// 离开组件时守卫
beforeRouteLeave: (to, from, next) => {
// 2. 离开组件时弹出对话框
if (confirm('是否离开页面?')) {
next();
} else {
next(false); // 阻止离开
}
}
};
</script>
代码解析如下。
-
首先进入订单组件,要把 islogin 的值修改为 1。
-
离开组件时,设置对话框提醒,运行结果如图 7-8 所示。
