Vue3 - Not Found, 중첩된 라우트(Nested Routes)
목차
Not Found
라우터의 index.js
{
path: '/:pathMatch(.*)*',
name: 'NotFound',
component: NotFound
}
views/NotFoundView.vue
<script setup></script>
<template>
<div class="text-center py-5">
<h1>Oops!</h1>
<h2>404 Not Found</h2>
<div class="text-muted">요청한 페이지를 찾을 수 없습니다!</div>
<!-- {{ $route.params.pathMatch }} 슬래쉬로 구분하여 배열로 출력됨-->
<div class="mt-4">
<RouterLink to="/">
<button class="btn btn-primary">HOME</button>
</RouterLink>
</div>
</div>
</template>
<style scoped></style>
중첩된 라우트(Nested Routes)
실제 앱 UI는 일반적으로 여러 단계로 중첩 된 컴포넌트로 이루어져 있다. URL의 경로가 중첩된 컴포넌트의 특정 구조와 일치한다는 것
이게 무슨 말이냐면 특정 페이지로 들어갔을 때 일부 영역은 고정 시키고 특정 부분만 랜더링 해야하는 일이 발생할 수 있다.
이럴 때 원하는 영역에 <RouterView>
를 선언하면 된다.
그러면 결과적으로 RouterView
안에 또 RouterView
가 있는 것, 중첩된 라우터 형태가 된다.
views/nested/NestedView.vue
<script setup></script>
<template>
<ul class="nav nav-pills">
<li class="nav-item">
<a class="nav-link active" aria-current="page" href="one">Nested One</a>
</li>
<li class="nav-item">
<a class="nav-link" href="two">Nested Two</a>
</li>
</ul>
</template>
<style scoped></style>
페이지 컴포넌트를 만들고, 라우터 맵핑 후 TheHeader.vue
에서 라우터 링크를 하나 연결해준다.
<li class="nav-item">
<RouterLink class="nav-link" active-class="active" to="/nested">Nested</RouterLink>
</li>
/nested
url로 넘어왔을 때 Vue 라우터 구성 컴포넌트를 보면 TheView
안에 RouterView
가 있기 때문에
목록 경로에 따라서 해당 페이지의 영역만 변경되어 렌더링 된다.
NestedView.vue
안에 <RouterView>
를 추가한다. a태그도 라우터링크 태그로 바꿔주자.
<script setup></script>
<template>
<ul class="nav nav-pills">
<li class="nav-item">
<RouterLink to="one" class="nav-link" active-class="active"> Nested One</RouterLink>
</li>
<li class="nav-item">
<RouterLink to="two" class="nav-link" active-class="active"> Nested Two</RouterLink>
</li>
<hr class="my-4" />
<RouterView></RouterView>
</ul>
</template>
<style scoped></style>
views/nested
경로 안에 NestedOneView.vue
와 NestedTwoView.vue
를 생성한다.
one.vue
<template>
<div class="card">
<div class="card-header">Nested One</div>
<div class="card-body">
<h5 class="card-title">Special title treatment</h5>
<p class="card-text">With supporting text below as a natural lead-in to additional content.</p>
<a href="#" class="btn btn-danger">Go somewhere</a>
</div>
</div>
</template>
two.vue
<template>
<div class="card">
<div class="card-header">Nested Two</div>
<div class="card-body">
<h5 class="card-title">Special title treatment</h5>
<p class="card-text">With supporting text below as a natural lead-in to additional content.</p>
<a href="#" class="btn btn-primary">Go somewhere</a>
</div>
</div>
</template>
Children
그리고 중첩된 라우터를 설정한다.
router/index.js
{
path: '/nested',
name: 'Nested',
component: NestedView,
children: [
{
path: 'one',
name: 'NestedOne',
component: NestedOneView
},
{
path: 'two',
name: 'NestedTwo',
component: NestedTwoView
}
]
}
/nested 선언 객체 안에 children
속성을 추가하여 배열 값으로 똑같이 라우터를 집어넣는다. children
일 때는 path에 /
가 부모를 통해 자동으로 붙기 때문에 빼도록 한다. /
가 붙으면 절대경로가 되어버리니까 주의하자.
/nested/one
, /nested/two
로 라우터가 연결되어 이동할 수 있다. 고정 레이아웃은 페이지가 이동되어도 유지하고, 페이지 컴포넌트의 컨텐츠 영역이 다르게 렌더링이 가능하게 활용할 수 있다.
그리고 Vue에서는 라우터 이동할 때 /
를 안붙이면 현재 부모 URL 기준으로 페이지가 이동되기 때문에
children
으로 맵핑 된 NestedOneView, NestedTwoView
는 NestedView.vue
의 /nested
경로가 자동으로 붙어 /nested/one
, /nested/two
페이지로 이동할 수 있다.
이 방법이 혼란스럽다면 절대경로 URL
/nested/one
, /nested/two
로 이동선언을 하면 된다. 아래 코드 참고
<!-- 현재 페이지 컴포넌트가 상위라면 하위 URL은 부모 path와 슬래쉬를 생략 -->
<li class="nav-item">
<RouterLink to="one" class="nav-link" active-class="active"> Nested One</RouterLink>
</li>
<li class="nav-item">
<RouterLink to="two" class="nav-link" active-class="active"> Nested Two</RouterLink>
</li>
<!-- 확실한 다른 방법으로는 -->
<li class="nav-item">
<RouterLink to="/nested/one" class="nav-link" active-class="active"> Nested One</RouterLink>
</li>
<li class="nav-item">
<RouterLink to="/nested/two" class="nav-link" active-class="active"> Nested Two</RouterLink>
</li>
그리고 /nested
라는 경로에 아무것도 없는데 여기에 메인(홈)을 구성하고 싶다면 아래와 같이 구성할 수 있다.
routes/index.js
children 값에 상단에 추가한다.
{
path: '/nested',
name: 'Nested',
component: NestedView,
children: [
{
path: '',
name: 'NestedHome',
component: NestedHomeView
},
{
path: 'one',
name: 'NestedOne',
component: NestedOneView
},
{
path: 'two',
name: 'NestedTwo',
component: NestedTwoView
}
]
}
views/nested/NestedHomeView.vue
<script setup></script>
<template>
<div class="card">
<div class="card-header">Nested Home</div>
<div class="card-body">
<h1 class="card-title">Nested routes home</h1>
</div>
</div>
</template>
<style scoped></style>
router.replace
router.push
와 같은 역할을 하지만 차이점이 있다.
새로운 히스토리 항목에 추가하지 않고 탐색하는 것이 replace
함수이다.
사용 방식은 두 가지가 있는데
선언 방식
<router-link :to=".." replace>
프로그래밍 방식
router.replace(...)
router.push
함수에 replace: true
속성을 추가하여 동일하게 동작도 할 수 있다.
router.push({
path: '/',
replace: true
}})
// 같은 의미
router.replace({ path: '/' })
router.go(n)
이 함수는 window.history.go()
함수와 비슷하게 히스토리 스택에서 앞, 뒤로 이동하며 매개 변수에는 음수/양수 값을 넣으며 조정한다.
-1 == history.back() 뒤로가기
1 == history.forward() 앞으로가기
n == 지정한 만큼 이동
지정한 값만큼 이동할 기록이 없으면 실패함
'🖥Frontend > Vue.js' 카테고리의 다른 글
IntelliJ Vue 컴포넌트 파일 생성 꿀팁 (0) | 2023.04.04 |
---|---|
Vue3 - 페이지 컴포넌트에 Props 전달과 ref, reactive.. (복사/재귀함수) (2) | 2023.01.31 |
Vue3 - 게시판 CRUD - UI 구성, 라우터 맵핑 (0) | 2023.01.31 |
Vue3 - 뷰 라우터 Vue Router (0) | 2023.01.31 |
Vue3 - 프로젝트 구성, ESLint, Prettier 설정, Bootstrap 적용 (0) | 2023.01.31 |
댓글