티스토리 뷰
네비게이션 가드는 이름에서 알 수 있듯이 리다이렉션하거나 취소하여 네비게이션을 보호하는데 사용됩니다. 전역, 라우트별, 컴포넌트별로 네비게이션 가드를 등록하여 사용할 수 있습니다. 이번 포스트에서는 전역, 라우트별, 컴포넌트 각각의 방법으로 네비게이션 가드를 등록하는 방법을 이야기 하도록 하겠습니다.
params나 query가 변경되어도 네비게이션 가드는 실행되지 않습니다. 변경되는 시점을 알고 싶다면, vue 옵션 중 watch
옵션에 $router
객체를 등록하거나 컴포넌트 가드인 beforeRouteUpdate
(2.2 버전에서 추가 됨)를 사용해야 합니다.
1. Global Before 가드
router.beforeEach
를 사용하여 Gobal Before 가드를 사용할 수 있습니다.
const router = new VueRouter({ ... })
router.beforeEach((to, from, next) => {
// ...
})
Gobal Before 가드는 모든 네비게이션의 생성된 순서에 따라 호출 됩니다. 이 가드는 비동기적으로 종료(resolved) 될 수 있습니다. 모든 훅들이 종료(resolved)되기 전까지 네비게이션은 중지된 상태가 됩니다.
Global Before 가드의 전달인자
to: Route
: 이동할 타켓의 Route 객체입니다.from: Route
: 현재의 Route 객체(네비게이션 이동하기 전의 Route 객체)입니다.next: Function
: 이 함수를 호출해야 훅이 종료(resolved) 됩니다. 어떠한 동작을 할 것인지는 next 함수어 어떤 인자값이 전달되는지에 따라 결정됩니다.next()
: 다음 훅으로 이동됩니다. 다른 훅으로 이동할 수 있도록 승인을 하는 동작입니다.next(false)
: 현재 네비게이션을 종료합니다.next('/')
또는next({ path: '/' })
: 인자로 전달된 경로로 이동합니다. 현재의 네비게이션은 중단되고 새로운 네비게이션이 시작됩니다.next
함수에는replace: true
나name: 'home'
,<router-link>
의to
에 전달되어야 하는 prop나router.push
함수에 전달되어야 하는 값들 모두 인자값으로 사용 가능합니다.next(error)
: (2.4.0 이후)next
함수에 전달된 값이Error
인스턴스이면, 네비게이션이 중지되고, 에러는router.onError()
의 콜백에 전달됩니다.
next
함수는 항상 호출되어야 합니다. 호출되지 않으면 훅은 종료되지 않습니다.
2. Global Resolve 가드
router.beforeResolve
를 사용하여 Global 가드를 등록할 수 있습니다. router.beforeEach
와 유사합니다. 차이점은 모든 in-component 가드와 비동기 라우터 컴포넌트가 종료 된 후, 네비게이션이 승인되기 바로 전에 호출된다는 것입니다.
3. Global After 훅
router.afterEach
를 사용하여 Global 훅을 등록할 수 있습니다. 가드라고 이야기하지 않고 훅이라고 이야기 한 이유는 네비게이션을 보호하는 가드의 역할을 하는 next
함수가 인자로 전달되지 않기 때문입니다.
router.afterEach((to, from) => {
// ...
})
4. Route 별 가드
beforeEnter
가드는 route 설정 객체에 직접 정의하여 사용합니다.
const router = new VueRouter({
routes: [
{
path: '/foo',
component: Foo,
beforeEnter: (to, from, next) => {
// ...
}
}
]
})
5. 컴포넌트 내부 가드
라우트 컴포넌트 내부의 네비게이션 가드를 정의 할 수 있습니다. 컴포넌트 내부 가드는 beforeRouteEnter
, beforeRouteUpdate
, beforeRouteLeave
3가지가 있습니다.
const Foo = {
template: `...`,
beforeRouteEnter (to, from, next) {
// called before the route that renders this component is confirmed.
// does NOT have access to `this` component instance,
// because it has not been created yet when this guard is called!
},
beforeRouteUpdate (to, from, next) {
// called when the route that renders this component has changed,
// but this component is reused in the new route.
// For example, for a route with dynamic params `/foo/:id`, when we
// navigate between `/foo/1` and `/foo/2`, the same `Foo` component instance
// will be reused, and this hook will be called when that happens.
// has access to `this` component instance.
},
beforeRouteLeave (to, from, next) {
// called when the route that renders this component is about to
// be navigated away from.
// has access to `this` component instance.
}
}
beforeRouteEnter
가드
beforeRouteEnter
가드는 네비게이션이 승인된기 전(새로 진입하는 컴포넌트가 생성되기 전)에 호출되기 때문에 this
를 사용할 수 없습니다. 하지만 next
함수의 콜백은 네비게이션이 승인 된후 호출 되기 때문에 이 콜백을 사용하여 컴포넌트 인스턴스에 접근할 수 있습니다.
beforeRouteEnter (to, from, next) {
next(vm => {
// access to component instance via `vm`
})
}
beforeRouteEnter
에서만 next
함수의 콜백함수를 지원합니다.
beforeRouteUpdate
가드
beforeRouteUpdate
가드에서는 this
를 사용할 수 있습니다. next
의 콜백함수를 지원할 필요가 없어 next
의 콜백함수를 지원하지 않습니다.
beforeRouteUpdate (to, from, next) {
// just use `this`
this.name = to.params.name
next()
}
beforeRouteLeave
가드
beforeRouteLeave
가드는 에디터가 값을 저장하지 않고 페이지를 벗어나는 것을 방지하는데 유용한 가드입니다. next(false)
를 호출하면 네비게이션이 중단됩니다.
beforeRouteLeave (to, from, next) {
const answer = window.confirm('Do you really want to leave? you have unsaved changes!')
if (answer) {
next()
} else {
next(false)
}
}
6. 전체 네비게이션 시나리오
- 네비게이션이 트리거 됨.
- 비활성되 된 컴포넌트에서 Leave 가드가 호출 됨.
- 전역 가드인
beforeEach
가드가 호출 됨. - 재사용 된느 컴포넌트에서
beforeRouteUpdate
가드가 호출 됨. - route 설정에 정의 된
beforeEnter
가드가 호출 됨. - 비동기 라우터 컴포넌트가 해결 됨.
- 활성화 되는 컴포넌트의
beforeRouteEnter
가드가 호출 됨. - 전역 가드인
beforeResolve
가드가 호출 됨. - 네비게이션이 완료 됨.
- 전역 훅인
afterEach
훅이 호출 됨. - DOM 업데이트가 트리거 됨.
beforeRouteEnter
가드의next
함수에 전달된 콜백 함수가 호출 됨.
참고
'Vue.JS' 카테고리의 다른 글
[vue-router] 트랜지션 (0) | 2019.06.16 |
---|---|
[vue-router] 라우터 메타 필드 (0) | 2019.06.16 |
[vue-router] HTML5 히스토리 모드 (0) | 2019.06.14 |
[vue-router] 라우터 컴포넌트에 props 전달 (0) | 2019.06.13 |
[vue-router] Redirect 와 Alias (0) | 2019.06.12 |