Day21-路由守卫(Navigation Guards)

Navigation Guards有点像是生命周期的概念,变更路由前後时可以先执行一些动作,分别有「全域」、「路由」和「元件」三个Hook可以使用。

beforeEach(全域)

在路由被执行之前都会先经过这

const router = new VueRouter({ ... })
	router.beforeEach((to, from, next) => {
		//例如:身分验证
		return await canUserAcess(to)
})
//canUserAcess(to)->false 路由的切换会禁止
//canUserAcess(to)->true/undefined 路由正常执行 

router.beforeEach的callback函式中

  • to 即将进入的路由
  • from 从何处进入的路由
  • next 继续往下执行callback,没有呼叫则路由中断(Vue Router4开始可省略)
router.beforeEach((to, from, next) => {
  if (to.name !== 'Login' && !isAuthenticated){ 
		next({ name: 'Login' })
	}
  else{ 
		next()
	}
})

//Vue Router4 後可以写成
router.beforeEach((to) => {
  if (to.name !== 'Login' && !isAuthenticated){ 
		return({ name: 'Login' })
	}
})

beforeResolve(全域)

在路由跳转前触发,但晚於router.beforeEach,以及非同步路由元件解析後才被调用。

router.beforeResolve((to, from, next) => { 
	// do something... 
});

afterEach(全域)

跳转後触发,callback函式只有tofrom以及failure(表示路由转跳失败)。可以使用router.afterEach来搭配GA追踪类的工具,来记录使用者浏览纪录:

router.afterEach((to, from, failure) => { 
	if (!failure) { 
		sendToAnalytics(to.fullPath); 
	} 
	else { 
		// fallback... 
	} 
});

beforeEnter(路由)

beforeEach作用一样,但只能在route物件内注册。可以依照routers规则选择是否注册,而beforeEach注册後整个程序路由都会进入此hook中

const router = new VueRouter({
  routes: [
    {
      path: '/foo',
      component: Foo,
      beforeEnter: (to, from) => {
        return false
      }
    }
  ]
})

元件内的Hook

  1. beforeRoutereEnter在路由尚未进入元件时被调用,callback有to,fromnext

    注意!! 在此处因为元件实体尚未建立,故拿不到this

    beforeRouteEnter (to, from, next) { 
    	// 没有 this!!! 
    	next(vm => { 
    		// 可以透过 vm 指向元件实体 
    	}); 
    }
    
  2. beforeRouterUpdate路由被改变,但元件本身仍是同一个时被调用,例如/users/1换成/users/2路由更新但使用同一个元件。

    beforeRoutereEnter的callback相同,只差了next()

    // post.vue 
    export default { 
    	data() { 
    		return { 
    			post: null, 
    			error: null, 
    		} 
    	}, 
    	beforeRouteEnter(to, from, next) { 
    		// 因元件未建立,只能透过 next 来取得实体 
    		getPost(to.params.id, (err, post) => { 
    			next(vm => vm.setData(err, post)) 
    		}) 
    	}, 
    	async beforeRouteUpdate(to, from) { 
    		// 路由更新前,可使用this指向元件实体了! 
    		this.post = null; 
    		try { 
    			this.post = await getPost(to.params.id) 
    		} catch (error) { 
    			this.error = error.toString() 
    		} 
    	}, 
    }
    
  3. beforeRouterLeave路由离开元件时调用,参数有tofrom。通常用在询问使用者是否要转跳到另一个路由使用:

    beforeRouteLeave (to, from) {
      const answer = window.confirm('是否离开此页?')
      if (answer) {
        return false
      }
    }
    

Navigation Guards执行顺序

切换路由时,依序会进行:

  • beforeRouteLeave 离开目前路由 (元件)
  • beforeEach 开始进入新路由之前 (全域)
  • beforeEnter 开始进入新路由之前 (路由)
  • beforeRouteEnter 路由尚未进入该元件时 (元件)
  • beforeResolve 路由与所搭配的元件已被解析 (全域)
  • afterEach 当路由跳转结束後 (全域)
  • beforeCreate 元件实体建立前 (Vue Hook)
  • created 元件实体已建立 (Vue Hook)
  • beforeMount 元件实体挂载前 (Vue Hook)
  • mounted 元件实体挂载完成 (Vue Hook)
  • beforeRouteEnter 内的 next() 回呼函式
  • beforeRouteUpdate 当路由更新时 (仅限同属一个元件的情况,也可能完全不会发生)

参考资料

Router 进阶应用 Day 10
https://ithelp.ithome.com.tw/articles/10214740
Navigation Guards
https://router.vuejs.org/guide/advanced/navigation-guards.html


<<:  Day-22 :何谓模糊搜寻?

>>:  [区块链&DAPP介绍 Day28] Dapp 实战 留言版 - 2

Youtube Data API 教学 - 基本分类介绍 list.part

「鲑鱼均,因为一场鲑鱼之乱被主管称为鲑鱼世代,广义来说以年龄和脸蛋分类的话这应该算是一种 KNN 的...

连续 30 天 玩玩看 ProtoPie - Day 9

做出左右滑动的互动行为 今天要来操作这个 Container ,其实就可以把它想成「一组」东西就好了...

33岁转职者的前端笔记-DAY 14 排版技巧小笔记-标签属性元素及定位方法

区块元素(block) 预设为区块元素的标签有:h1~h6,p,div,section,header...

[Day 03] 用 Gradle 安装 Exposed 框架

Kotlin 专案建立完成之後,再来就是安装 Exposed 框架了。毕竟这是这系列文章的重头戏嘛!...

Day 1 - 浅谈 Kubernetes 的架设与管理

本文将於赛後同步刊登於笔者部落格 有兴趣学习更多 Kubernetes/DevOps/Linux 相...