Vue-router에 대해 알아보자! (1)

Sian·2020년 10월 21일
0

Vue Router 알아보기

목록 보기
1/2
post-thumbnail

1. Vue-router란?

Vue.js의 공식 라우터로 중첩 라우트/매핑, 컴포넌트 기반의 라우터 설정, 라우터 파라미터/쿼리, 히스토리/해시 모드 등의 기능을 가지고 있다.
Typescript를 사용할 시 vue-router@3.0+와 vue@2.5+ 버전을 사용해야 한다.

2. 동적 라우팅?

일정한 패턴의 라우트를 하나의 컴포넌트에 연결하는 방법을 동적 라우트 매칭이라고 한다.

<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>

<div id="app">
  <p>
    <router-link to="/user/foo">/user/foo</router-link>
    <router-link to="/user/bar">/user/bar</router-link>
  </p>
  <router-view></router-view>
</div>
const User = {
  template: `<div>User {{ $route.params.id }}</div>`
}

const router = new VueRouter({
  routes: [
    { path: '/user/:id', component: User }
  ]
})

const app = new Vue({ router }).$mount('#app')

위의 코드에서 /user/foo와 /user/bar는 모두 같은 컴포넌트에 매핑된다.
이렇게 :id에 해당하는 동적 세그먼트는 콜론으로 표시되고, 라우트가 일치하면 동적 세그먼트의 값은 모든 컴포넌트에서 this.$route.params로 표시된다. (이 때, composition api를 쓴다면 this가 아닌 vm 아래에 $route가 있다.)

vue-router의 github을 확인하면, router 객체가 제공하는 정보는 아래와 같다.

export interface Route {
  path: string
  name?: string | null
  hash: string
  query: Dictionary<string | (string | null)[]>
  params: Dictionary<string>
  fullPath: string
  matched: RouteRecord[]
  redirectedFrom?: string
  meta?: any
}

* 동적 라우팅 시 주의해야 할 점
동일한 컴포넌트 인스턴스가 재사용되기 때문에 컴포넌트의 라이프 사이클 훅이 호출되지 않음
이 경우 해결책은 두 가지가 있다.
첫 째는, $route 객체를 watch를 사용하여 변경 사항을 반영하는 것이다.
둘 째는, beforeRouteUpdate라는 네비게이션 가드를 사용하는 것이다.(추후 설명)

동적 라우트 매칭 우선순위는 라우트 정의 순서에 따라 결정된다. 즉, 경로가 코드에 더 먼저 정의될수록 우선 순위가 높아진다.

3. 중첩 라우팅?

하나의 컴포넌트가 다시 하위 컴포넌트를 포함하는 경우, 라우팅도 중첩해야 한다.

위의 그림과 같은 경우에 중첩 라우팅이 필요하다. 즉, 앞서 동적 라우팅 때 설명했던 /user/:id를 사용하고 하위 컴포넌트를 변경하고 싶은 경우이다.
이런 경우에는, 아래와 같이 children을 사용한다.

const router = new VueRouter({
  routes: [
    { path: '/user/:id', component: User,
      children: [
        {
          // /user/:id/profile 과 일치 할 때
          // UserProfile은 User의 <router-view> 내에 렌더링 됩니다.
          path: 'profile',
          component: UserProfile
        },
        {
          // /user/:id/posts 과 일치 할 때
          // UserPosts가 User의 <router-view> 내에 렌더링 됩니다.
          path: 'posts',
          component: UserPosts
        }
      ]
    }
  ]
})

중첩 라우트에서 알아두어야 할 사항 중 하나는, children의 path에 '/'를 사용할 경우엔 루트 경로로 취급되어 /user/:id에 '/'를 매칭해둔 컴포넌트를 url을 중첩시키지 않고도 사용할 수 있다는 것이다.
예를 들어, 위의 코드에서

const router = new VueRouter({
  routes: [
    { path: '/user/:id', component: User,
      children: [
      	{
          // 루트 경로로 취급
          path: '/',
          component: UserMain
        },
        {
          path: 'profile',
          component: UserProfile
        }
      ]
    }
  ]
})

위와 같이 path를 '/'로 하는 children을 만들면, /user/:id/main을 하지 않고 /user/:id만 하더라도 userMain 컴포넌트가 렌더링 된다는 것이다.

 

4. 이름을 가지는 라우트와 이름을 가지는 뷰

이름을 가지는 라우트(Named Route)는 라우트 정보에 고유한 이름을 부여하는 것이며 이를 통해 가 아닌 부여된 라우트 이름으로 내비게이션이 가능하다. Named route를 활용하면 URI 관리가 보다 용이해진다. 이름을 가지는 뷰는 https://router.vuejs.org/kr/guide/essentials/named-views.html <- 공식 문서의 설명에 잘 나와있다.

 

5. 라우트 컴포넌트에 속성 전달하기

앞서 나온 예시들은 /user/:id의 id 부분을 컴포넌트에서 사용하기 위해서는 $route 객체에 접근하여 $route.params.id에서 값을 꺼내와야 했지만, 이러한 방식은 컴포넌트가 특정한 URL에 종속되기 때문에 지양해야 한다.
대안으로 라우트 컴포넌트에 속성을 전달하는 방법이 있다.

1. Boolean 모드

const router = new VueRouter({
  routes: [
    { path: '/user/:id', component: User, props: true },
  ]
})

위와 같이 props: true를 주면, 컴포넌트에서 props로 id를 받아 사용할 수 있다.

2. 객체 모드

{ ..생략.. props: { invalidUserId: true } }

정적인 props를 넘겨줄 때 용이하다.

3. 함수 모드

{ ..생략.. props: route => ({ nextPath: route.query.nextPath || '/' }) }

라우트와 props 간에 커스텀 로직이 필요할 경우 용이하다.

reference

  • Vue.js 퀵 스타트
profile
https://sian-log-siyeons.vercel.app/ 이 곳으로 이전하였습니다.

0개의 댓글