[vue.js] 네비게이션 가드

채병주·2021년 1월 13일
0

vue-js

목록 보기
8/8

네비게이션 가드를 통해 잘못된 페이지 이동 시 리다이렉트/취소하여 Nativation을 보호하기

1. Purpose

웹페이지 내에서 페이지 간의 이동을 할 때, URL에 따라서 유효하지 않은 URL인 경우가 있을 수 있다. 몇 가지 상황에 따라 예시를 분류하자면,

  1. 먼저 동적 라우트 매칭을 통해 컴포넌트로 이동하는 경우, 상황에 따라 올바르지 않은 자료형 or 범위의 parameter를 임의로 입력할 수도 있다. 예를 들어 https://example.com/history/<year> 라는 주소를 생각해보자. parameter로 연도를 받아서 그 값에 따라 데이터를 불러오는 화면이라면, parameter로 문자열이 들어온다면(ex. https://example.com/history/hello ) 제대로 된 데이터를 불러올 수 없을 것이다.

  2. 흔한 경우는 아니지만, 만약 페이지 이동 시에 이동 전 화면에 따라 다음 화면에서 표시하는 내용이 달라질 수도 있다.

  3. 그 외에도 특정 화면에 대한 접근 권한을 체크할 때에도 많이 사용한다고 한다.

위와 같이 내가 공부한 바로는 크게 3가지 정도의 경우로 나눌 수 있을 것 같다.

2. Usage

네비게이션 가드의 종류는 크게 3가지로 나눌 수 있다. 각각에 대해서 조금 더 자세히 알아보자. 이때 각각의 예시는 [1]Vue Router 공식 문서를 참고하였다.

1) 전역 가드

전역 가드는 '전역(Global)'이라는 단어가 개발 분야에서 일반적으로 사용되는 것처럼 모든 네비게이션에 대해 발생되는 네비게이션 가드이다. 즉, 페이지 이동이 발생할 때마다 실행되는 코드라고 보면 될 것 같다.

const router = new VueRouter({ ... })

router.beforeEach((to, from, next) => {
  // ...
})

위에서처럼 beforeEach 라는 메서드를 통해서 실행되며, 이 메서드는 3개의 parameter가 있다. to 의 경우 현재의 라우트, 즉 네비게이션을 통해 이동할 객체를 의미한다. from 의 경우는 현재 라우트로 오기 전 라우트를 의미한다. fromto 모두 자료형은 라우트 객체이다. next() 는 'hook을 해결하기 위해' 반드시 호출되어야 한다. 'hook을 해결한다'는 표현은 조금 추상적으로 이해가 된다. 대략적으로 이해한 바에 따르면, 유저의 사용 흐름 상에서 네비게이션 자체는 일시정지, next() 는 다시 재생하기 정도의 기능으로 이해하면 되지 않을까 싶다. next() 를 parameter 없이 사용한다면, 이동하려고 했던 라우트로 이동하지만, 만약 인자를 전달한다면 (ex. next('/') , next({ path: '/' })) 해당 라우트로 리다이렉트 한다. 이 경우 새로운 네비게이션이 시작된다고 한다. 그 외에도 next(false) 와 같이 인자로 false 값을 전달하면 from 의 라우트로 다시 이동하게 된다. 아마 접근 권한 등을 확인할 때 사용하지 않을까 싶다(?)

2) 라우트 별 가드

전역 가드와 다르게 특정 라우트 객체에 대해서만 네비게이션 가드를 설정할 수 있다. 이 경우 beforeEnter 를 사용한다. 사용 방법의 경우 전역 가드와 동일하다.

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

3) 컴포넌트 내부 가드

라우트 별 가드와 유사하면서도 조금씩 다르다. beforeRouteEnterbeforeRouteLeave 를 컴포넌트 안에 직접 정의하여 네비게이션 가드를 사용할 수 있다.

const Foo = {
  template: `...`,
  beforeRouteEnter (to, from, next) {
    // 이 컴포넌트를 렌더링하는 라우트 앞에 호출됩니다.
    // 이 가드가 호출 될 때 아직 생성되지 않았기 때문에
    // `this` 컴포넌트 인스턴스에 접근 할 수 없습니다!
  },
  beforeRouteLeave (to, from, next) {
    // 이 컴포넌트를 렌더링하는 라우트가 이전으로 네비게이션 될 때 호출됩니다.
    // `this` 컴포넌트 인스턴스에 접근 할 수 있습니다.
  }
}

하지만 beforeRouteEnter 의 경우 컴포넌트 생성 이전이기 때문에 this 에 접근을 할 수는 없다. 이 경우, next() 함수에서의 콜백을 통해 인스턴스에 접근할 수 있다.

beforeRouteEnter (to, from, next) {
  next(vm => {
    // `vm`을 통한 컴포넌트 인스턴스 접근
  })
}

반대로 이름과 라이프 사이클을 생각하면 당연하지만, beforeRouteLeave 에서는 this 에 직접 접근할 수 있다. 주로 사용자가 저장하지 않은 편집 내용을 두고 실수로 페이지를 이동하는 것을 방지하는데 사용된다고 한다.

cf. parameter 변경 사항에 반응하기

동적 라우트 매칭에서 parameter만 변경되는 경우, 컴포넌트의 라이프 사이클 훅이 호출되지 않는다. 따라서 네비게이션 가드 중 하나인 beforerouteUpdate 를 사용하면 새로운 훅을 만들 수 있다.

const User = {
  template: '...',
  beforeRouteUpdate (to, from, next) {
    // react to route changes...
    // don't forget to call next()
  }
}

3. Reference

  1. (공식 문서) 네비게이션 가드 [link]
  2. 네비게이션 가드 [link]
  3. (공식 문서) 동적 라우트 매칭 - Params 변경 사항에 반응하기 [link]
profile
개발 외의 일들에 더 흥미를 가지는 개발자. Interested in Web, Generative AI, UI/UX.

0개의 댓글