라우트 매칭 문법
대부분의 애플리케이션은 동적 라우트 매칭에서 본 것처럼 /about 같은 정적 라우트와 /users/:userId 같은 동적 라우트를 사용하겠지만, Vue Router는 그보다 훨씬 더 많은 기능을 제공합니다!
TIP
단순화를 위해 모든 라우트 레코드는 path 값에 집중할 수 있도록 component 속성을 생략합니다.
params 안의 사용자 정의 regex
:userId 같은 param을 정의할 때 내부적으로는 URL에서 params를 추출하기 위해 ([^/]+)라는 regex(/가 아닌 문자가 최소 한 개)를 사용합니다. 이는 param 내용에 따라 두 라우트를 구분해야 하는 경우가 아니라면 잘 동작합니다. /:orderId와 /:productName 두 라우트를 생각해 보면 둘 다 정확히 같은 URL에 매치되므로, 이를 구분할 방법이 필요합니다. 가장 쉬운 방법은 이를 구분해 주는 정적 섹션을 경로에 추가하는 것입니다:
const routes = [
// /o/3549에 매치됩니다
{ path: '/o/:orderId' },
// /p/books에 매치됩니다
{ path: '/p/:productName' },
]하지만 어떤 시나리오에서는 /o나 /p 같은 정적 섹션을 추가하고 싶지 않을 수 있습니다. 대신 orderId는 항상 숫자이고 productName은 무엇이든 될 수 있으므로, 괄호 안에 param용 사용자 정의 regex를 지정할 수 있습니다:
const routes = [
// /:orderId -> 숫자에만 매치됩니다
{ path: '/:orderId(\\d+)' },
// /:productName -> 그 외 모든 것에 매치됩니다
{ path: '/:productName' },
]이제 /25로 이동하면 /:orderId에 매치되고, 다른 어떤 값으로 이동하면 /:productName에 매치됩니다. 심지어 routes 배열의 순서도 중요하지 않습니다!
TIP
JavaScript 문자열 안에서 실제 백슬래시 문자를 전달하려면 \d를 \\d로 쓴 것처럼 백슬래시(\)를 이스케이프 해야 한다는 점에 유의하세요.
닫는 괄호 )는 사용자 정의 regex의 끝을 나타내는 데 사용되므로, regex 내부에서(예: 중첩 그룹) 이를 이스케이프해야 합니다:
const routes = [
// regexp 안에 있는 그룹의 닫는 괄호가 이스케이프된 점에 주목하세요
{ path: '/:custom(something-(nested|other\\))' },
]반복 가능한 params
/first/second/third처럼 여러 섹션이 있는 라우트를 매치해야 한다면, param을 *(0개 이상) 또는 +(1개 이상)로 표시해 반복 가능하게 만들어야 합니다:
const routes = [
// /:chapters -> /one, /one/two, /one/two/three 등에 매치됩니다
{ path: '/:chapters+' },
// /:chapters -> /, /one, /one/two, /one/two/three 등에 매치됩니다
{ path: '/:chapters*' },
]이렇게 하면 문자열 대신 params 배열을 얻게 되며, 이름 있는 라우트를 사용할 때도 배열을 전달해야 합니다:
// given { path: '/:chapters*', name: 'chapters' },
router.resolve({ name: 'chapters', params: { chapters: [] } }).href
// /를 생성합니다
router.resolve({ name: 'chapters', params: { chapters: ['a', 'b'] } }).href
// /a/b를 생성합니다
// given { path: '/:chapters+', name: 'chapters' },
router.resolve({ name: 'chapters', params: { chapters: [] } }).href
// `chapters`가 비어 있으므로 Error를 throw합니다이들은 닫는 괄호 뒤에 추가하여 사용자 정의 regex와 결합할 수도 있습니다:
const routes = [
// 숫자에만 매치됩니다
// /1, /1/2 등에 매치됩니다
{ path: '/:chapters(\\d+)+' },
// /, /1, /1/2 등에 매치됩니다
{ path: '/:chapters(\\d+)*' },
]sensitive 및 strict 라우트 옵션
기본적으로 모든 라우트는 대소문자를 구분하지 않으며, 끝 슬래시가 있든 없든 매치됩니다. 예를 들어 /users 라우트는 /users, /users/, 심지어 /Users/에도 매치됩니다. 이 동작은 strict와 sensitive 옵션으로 구성할 수 있으며, 라우터 수준과 라우트 수준 모두에서 설정할 수 있습니다:
const router = createRouter({
history: createWebHistory(),
routes: [
// /users/posva에는 매치되지만 다음에는 매치되지 않습니다:
// - strict: true 때문에 /users/posva/
// - sensitive: true 때문에 /Users/posva
{ path: '/users/:id', sensitive: true },
// /users, /Users, /users/42에는 매치되지만 /users/ 또는 /users/42/에는 매치되지 않습니다
{ path: '/users/:id?' },
],
strict: true, // 모든 라우트에 적용됩니다
})선택적 매개변수
? 수정자(0개 또는 1개)를 사용해 매개변수를 선택적으로 표시할 수도 있습니다:
const routes = [
// /users와 /users/posva에 매치됩니다
{ path: '/users/:userId?' },
// /users와 /users/42에 매치됩니다
{ path: '/users/:userId(\\d+)?' },
]엄밀히 말하면 *도 매개변수를 선택적으로 표시하지만, ? 매개변수는 반복될 수 없습니다.
라우트 세그먼트에 선택적 매개변수 외에 다른 내용이 더 들어 있으면, 끝 슬래시가 없는 경로에는 매치되지 않습니다. 예:
/users/:uid?-:name?won't match/users, only/users/-or even/users/-//users/:uid(\\d+)?:name?won't match/users, only/users/,/users/2,/users/2/, etc
playground에서 매칭 문법을 직접 시험해 볼 수 있습니다
디버깅
왜 어떤 라우트가 매치되지 않는지 이해하거나 버그를 보고하기 위해, 라우트가 regex로 어떻게 변환되는지 깊이 살펴봐야 한다면 path ranker 도구를 사용할 수 있습니다. URL을 통해 라우트를 공유하는 것도 지원합니다.
느린 regex 피하기
사용자 정의 regex를 사용할 때는 느린 regex 패턴을 피해야 합니다. 예를 들어 .*는 어떤 문자와도 매치되며, 반복 수정자 * 또는 +와 결합되고 그 뒤에 다른 내용이 이어지면 심각한 성능 문제를 일으킬 수 있습니다:
const routes = [
// 탐욕적인 `.*` 뒤에 `*`와 정적 문자열이 이어지므로 매우 느린 regex가 만들어집니다
{ path: '/:pathMatch(.*)*/something-at-the-end' },
]실제로는 이런 모든 것과 매치되는 params를 URL의 맨 끝에서만 사용하세요. 경로 중간에서 필요하다면 반복 가능하게 만들지 마세요:
const routes = [
// `.*`가 끝에 있으므로 괜찮습니다
{ path: '/:pathMatch(.*)/something-at-the-end' },
]이 방식은 같은 라우트에 매치되지만 params 배열을 만들지 않으며 훨씬 빠릅니다.