导航守卫(Navigation Guard)可以在 3 个地方使用,包括全域、元件和路由。所谓导航守卫就是在访问页面之前,会像一个守卫拦截并执行你所设定的任务,执行後会跳转或取消访问该路由。常用情况例如是登入验证,意思是在用户载入页面前,验证此用户的 token 是否有效,有就放行,没有就导回登入页。另外,导航守卫有不同的 Hook 函式可使用,就如 Vue 也有它的生命周期(created
、 mounted
等等)。但注意,不同的守卫各自都有自己一套 Hook 方法。
注意:Vue 3 是使用 Vue Router 4.x。Vue 2 是使用 Vue Router 3.x。 两者某些语法会有不同。因此在查看文件时务必留意!
以下主要讲解 Vue 3 (Vue Router 4.x)的做法。今天主题比较直白,的确没有什麽概念要理解,但也会举出自己曾经使用过的例子作解说。
每次进入任何一个路由前都会作拦截,并执行你在导航守卫里写下的任务。这些函式同样会以非同步方式执行。
执行次序:
使用情景:身分验证。
beforeEach()
一样,在进入路由前呼叫。但它会在 beforeEach()
後,并且在所有路由、元件的导航守卫都执行完,最後才会呼叫并执行。使用情景:呼叫 API,取得远端资料。
使用情景:像 GA 追踪工具一样记录使用者浏览纪录。
结果跳转路由後才呼叫。
Hook 函式如下:
const router = createRouter({ ... })
router.beforeEach(async (to, from, next) => {
// to:使用者要跳转的路由
// from:使用者前一个访问的路由
// 回传 false 取消跳转,true / undefined(预设)容许跳转
return false
// next 参数在 Vue Router 4 并非必须
})
router.beforeResolve(async (to, from, next) => {
// do something...
})
router.afterEach((to, from, failure) => {
// 因为 afterEach 是在路由跳转结束後才触发,因此没有 next
// failure 参数表示路由跳转失败
})
注意:
next
参数,在 Vue Router 3 (即是 Vue 2 )是必须,否则 beforeEach
这个 hook 函式就不会被 resolve 并且报错。官方例子如下:router.beforeEach((to, from, next) => {
if (to.name !== 'Login' && !isAuthenticated) next({ name: 'Login' })
else next()
})
关於在 Vue Router 3 的 next 参数其他用法,详情参考官方文件。
在 4.x 版本的 Vue Router 文件里,官方表示有机会移除 next 参数。因此不建议使用。
这里简单示范一下自己使用导航守卫来验证身份的做法。我当时是透过在 cookies 存放使用者登入时所取得的 token,来证明此使用者已登入。换言之,如果在 cookies 里没有 token,或者 token 失效,代表此使用者目前没登入,并需要跳转回登入页。
以下例子,我使用了 js-cookie 插件来操作 cookie。
router / index.js
import Cookies from 'js-cookie';
consr routes = [
{
path: '/',
component: Login // 首页是登入页
},
...
]
const router = createRouter({
history: createWebHashHistory(),
routes,
});
// 使用全域导航守卫
// 每次跳转页面都检查是否有 cookies
router.beforeEach(to => {
const token = Cookies.get('userToken');
// 登入页(首页)不用验证
if (to.fullPath === '/') return;
if (!token || !validateToken(token)) {
// 可能是因为 token 无效,所以需要移除此使用者的 token
Cookies.remove('userToken');
return '/';
}
}
// 验证成功,可以放行
return true;
});
如果没有加 if (to.fullPath === '/') return;
,就会出现死循环问题。因为跳转到首页时,守卫发现首页也没有验证成功,於是再次跳转到页面,造成无限循环:
[Vue Router warn]: Detected an infinite redirection in a navigation guard when going from "/" to "/". Aborting to avoid a Stack Overflow. This will break in production if not fixed.
[Vue Router warn]: Unexpected error when starting the router: Error: Infinite redirect in navigation guard at eval
只有在进入某一路由时,才会触发此导航守卫。 重点如下:
router.beforeEnter()
这 Hook 函式。官方例子:
const routes = [
{
path: '/users/:id',
component: UserDetails,
beforeEnter: (to, from) => {
// reject the navigation
return false
},
},
]
注意:如果该路由的 params、query、hash 有变化,也不会触发守卫。例如 /user/1
到 /users/2
,或者 /user/1/#info
到 /user/2/#detail
。
遇到要重用守卫的情况,可使用阵列。
官方例子:
const routes = [
{
path: '/users/:id',
component: UserDetails,
beforeEnter: [removeQueryParams, removeHash],
},
{
path: '/about',
component: UserDetails,
beforeEnter: [removeQueryParams],
},
]
在某元件设定守卫。元件守卫可使用的 Hook 函式:
this
。
this
。写法与在元件里使用生命周期一样:
data() {
return { ... }
},
beforeRouteEnter(to, from, next) {
// 无法使用 this
// 但可以透过 next 使用 this
next( vm => { ... })
},
beforeRouteUpdate(to, from) {
// do something...
},
beforeRouteLeave(to, from) {
// do something...
},
Vue 官网有提到所有 Hook 的执行次序,在此就不重复了:
截图至官方文件
重新认识 Vue.js - 4-4 路由守卫(Navigation Guards)
Vue Router - 导航守卫
因为它原本就会有一个storage是先帮你写好的,或许你第一次看到的时候会不知道这是甚麽,那我们会...
被动情蒐目的:了解目标 针对渗透目标,收集公开来源的情报,了解目标的情形,这些资料可能来自受测企业...
虽然 Gradle 内建不少任务,也有众多 Plugin 可以增加更多常用任务。但毕竟每个专案都是独...
那我们要开始着手处理我们的资料集了,今天会先做资料前处理的部分,其实不管是机器学习或是深度学习,只要...
LINE Developers:https://developers.line.biz/zh-ha...