Skip to content

Params를 사용한 동적 라우트 매칭

주어진 패턴의 라우트를 같은 컴포넌트에 매핑해야 하는 경우가 매우 자주 있습니다. 예를 들어 모든 사용자에 대해 같은 User 컴포넌트를 렌더링하되 사용자 ID만 다르게 하고 싶을 수 있습니다. Vue Router에서는 이를 위해 경로에 동적 세그먼트를 사용할 수 있으며, 이를 param 이라고 부릅니다:

js
import User from './User.vue'

// 이것들은 `createRouter`에 전달됩니다
const routes = [
  // 동적 세그먼트는 콜론으로 시작합니다
  { path: '/users/:id', component: User },
]

이제 /users/johnny/users/jolyne 같은 URL은 모두 같은 라우트에 매핑됩니다.

param 은 콜론 :으로 표시합니다. 라우트가 매치되면 그 params 값은 모든 컴포넌트에서 route.params로 노출됩니다. 따라서 User의 템플릿을 다음과 같이 바꿔 현재 사용자 ID를 렌더링할 수 있습니다:

vue
<template>
  <div>
    <!-- 현재 라우트는 템플릿에서 $route로 접근할 수 있습니다 -->
    User {{ $route.params.id }}
  </div>
</template>

같은 라우트에 여러 params 를 둘 수 있으며, 이들은 route.params의 대응하는 필드에 매핑됩니다. 예:

patternmatched pathroute.params
/users/:username/users/eduardo{ username: 'eduardo' }
/users/:username/posts/:postId/users/eduardo/posts/123{ username: 'eduardo', postId: '123' }

route.params 외에도 route 객체는 route.query(URL에 query가 있을 경우), route.hash 같은 유용한 정보도 노출합니다. 자세한 내용은 API Reference에서 확인할 수 있습니다.

이 예제의 동작하는 데모는 여기에서 확인할 수 있습니다.

Params 변경에 반응하기

params가 있는 라우트를 사용할 때 주의할 점은, 사용자가 /users/johnny에서 /users/jolyne로 이동할 때 같은 컴포넌트 인스턴스가 재사용된다는 것입니다. 두 라우트가 같은 컴포넌트를 렌더링하므로, 기존 인스턴스를 파괴하고 새 인스턴스를 만드는 것보다 더 효율적입니다. 하지만 이것은 컴포넌트의 일부 라이프사이클 훅이 호출되지 않는다는 뜻이기도 합니다.

같은 컴포넌트 안에서 params 변경에 반응하려면 route 객체의 원하는 항목, 이 경우 route.params를 watch하면 됩니다:

vue
<script setup>
import { watch } from 'vue'
import { useRoute } from 'vue-router'

const route = useRoute()

watch(
  () => route.params.id,
  (newId, oldId) => {
    // 라우트 변경에 반응합니다...
  }
)
</script>
vue
<script>
export default {
  created() {
    this.$watch(
      () => this.$route.params.id,
      (newId, oldId) => {
        // 라우트 변경에 반응합니다...
      }
    )
  },
}
</script>

또는 내비게이션 취소도 가능한 beforeRouteUpdate 내비게이션 가드를 사용할 수 있습니다:

vue
<script setup>
import { onBeforeRouteUpdate } from 'vue-router'
// ...

onBeforeRouteUpdate(async (to, from) => {
  // 라우트 변경에 반응합니다...
  userData.value = await fetchUser(to.params.id)
})
</script>
vue
<script>
export default {
  async beforeRouteUpdate(to, from) {
    // 라우트 변경에 반응합니다...
    this.userData = await fetchUser(to.params.id)
  },
  // ...
}
</script>

Catch all / 404 Not found 라우트

일반 params는 /로 구분된 URL 조각 사이의 문자만 매치합니다. 무엇이든 매치하고 싶다면, param 바로 뒤 괄호 안에 정규식을 추가한 사용자 정의 param regexp를 사용할 수 있습니다:

js
const routes = [
  // 모든 것을 매치하고 `route.params.pathMatch`에 넣습니다
  { path: '/:pathMatch(.*)*', name: 'NotFound', component: NotFound },
  // `/user-`로 시작하는 모든 경로를 매치하고 `route.params.afterUser`에 넣습니다
  { path: '/user-:afterUser(.*)', component: UserGeneric },
]

이 특정 시나리오에서는 괄호 안의 사용자 정의 regexp를 사용하고, pathMatch param을 선택적 반복 가능으로 표시합니다. 이렇게 하면 필요할 때 path를 배열로 나누어 해당 라우트로 직접 이동할 수 있습니다:

js
router.push({
  name: 'NotFound',
  // 현재 경로를 유지하고 첫 글자를 제거해 대상 URL이 `//`로 시작하지 않게 합니다
  params: { pathMatch: route.path.substring(1).split('/') },
  // 기존 query와 hash가 있다면 유지합니다
  query: route.query,
  hash: route.hash,
})

반복 가능한 params 섹션에서 더 자세히 볼 수 있습니다.

히스토리 모드를 사용 중이라면 서버도 올바르게 구성할 수 있도록 해당 지침을 따라야 합니다.

고급 매칭 패턴

Vue Router는 express에서 사용하는 문법에서 영감을 받은 자체 경로 매칭 문법을 사용하므로, 선택적 params, 0개 이상/1개 이상 요구 사항, 사용자 정의 regex 패턴 같은 다양한 고급 매칭 패턴을 지원합니다. 자세히 알아보려면 고급 매칭 문서를 확인하세요.

모두를 위한 문서 한글화