Nested Routes
Each URL provides different information on that resource:
각 URL은 해당 리소스에 대한 다양한 정보를 제공합니다.
- /event/2 - Event Details (information)
- /event/2/register - Event Register (to signup for the event)
- /event/2/edit - Event Edit (to edit the event)
Problem: Where do we place these components?
Solution: In their own folder. (event folder)
/event/2 | /src/views/event/Details.vue |
/event/2/register | /src/views/event/Register.vue |
/event/2/edit | /src/views/event/Edit.vue |
Problem: How do we create and route to these views?
There will be some duplicate code in this solution, which I’ll show you how to solve using Vue Router’s Nested Routes.
이 솔루션에는 중복된 코드가 있을 수 있는데, Vue Router의 중첩 경로를 사용하여 해결하는 방법을 보여 드리겠습니다.
Solution: Basic Routing
import { createRouter, createWebHistory } from 'vue-router'
import About from '@/views/About.vue'
import EventList from '@/views/EventList.vue'
import EventDetails from '@/views/event/Details.vue'
import EventRegister from '@/views/event/Register.vue'
import EventEdit from '@/views/event/Edit.vue'
const routes = [
{
path: '/',
name: 'EventList',
component: EventList
props: route => ({ page: parseInt(route.query.page) || 1 })
},
{
path: '/event/:id',
name: 'EventDetails',
props: true,
component: EventDetails
},
{
path: '/event/:id/register',
name: 'EventRegister',
props: true,
component: EventRegister
},
{
path: '/event/:id/edit',
name: 'EventEdit',
props: true,
component: EventEdit
},
...
Notice how I’m importing the components, using a dynamic route, and specifying props: true to send the id part of the URL as a prop into the components.
dynamic route를 사용하여 components,를 가져오고, URL의 ID 부분을 components에 prop 으로 보내기 위해 props: true를 지정하는 방법에 주목하세요.
/src/views/event/Details.vue
<template>
<div v-if="event">
<h1>{{ event.title }}</h1>
<div id="nav">
<router-link :to="{ name: 'EventDetails', params: { id } }"
>Details</router-link
>
|
<router-link :to="{ name: 'EventRegister', params: { id } }"
>Register</router-link
>
|
<router-link :to="{ name: 'EventEdit', params: { id } }"
>Edit</router-link
>
</div>
<p>{{ event.time }} on {{ event.date }} @ {{ event.location }}</p>
<p>{{ event.description }}</p>
</div>
</template>
<script>
import EventService from '@/services/EventService.js'
export default {
props: ['id'],
data() {
return {
event: null
}
},
created() {
EventService.getEvent(this.id)
.then(response => {
this.event = response.data
})
.catch(error => {
console.log(error)
})
}
}
</script>
Notice in here I display the event title, and then link to all of the event components.
여기에 이벤트 제목을 표시한 다음 모든 이벤트 구성 요소에 대한 링크를 표시합니다.
/src/views/event/Register.vue
<template>
<div v-if="event">
<h1>{{ event.title }}</h1>
<div id="nav">
<router-link :to="{ name: 'EventDetails', params: { id } }"
>Details</router-link
>
|
<router-link :to="{ name: 'EventRegister', params: { id } }"
>Register</router-link
>
|
<router-link :to="{ name: 'EventEdit', params: { id } }"
>Edit</router-link
>
</div>
<p>Regstration form here</p>
</div>
</template>
<script>
import EventService from '@/services/EventService.js'
export default {
props: ['id'],
data() {
return {
event: null
}
},
created() {
EventService.getEvent(this.id)
.then(response => {
this.event = response.data
})
.catch(error => {
console.log(error)
})
}
}
</script>
Problem: We’re repeating the header and navigation on each page.
You might notice that there’s some repetition going on. Specifically the header and the navigation.
특히 헤더와 navigation 에서 반복이 진행되고 있음을 알 수 있습니다.
Wouldn’t it be nice if we could eliminate that duplication? We also have the same API calling code in each component.
그 중복을 없앨 수 있다면 좋지 않을까요? 또한 각 구성 요소에는 동일한 API 호출 코드가 있습니다.
Solution: Nested Routes
we already have a top level <router-view> but we’ve stumbled upon an instance where we need another <router-view> or custom layout for all the event profile components.
이미 최상위 수준 <router-view>가 있지만 모든 이벤트 프로필 components에 대해 또 다른 <router-view> 또는 사용자 정의 레이아웃이 필요한 인스턴스를 우연히 발견했습니다.
/src/views/event/Layout.vue
<template>
<div v-if="event">
<h1>{{ event.title }}</h1>
<div id="nav">
<router-link :to="{ name: 'EventDetails', params: { id } }"
>Details</router-link
>
|
<router-link :to="{ name: 'EventRegister', params: { id } }"
>Register</router-link
>
|
<router-link :to="{ name: 'EventEdit', params: { id } }"
>Edit</router-link
>
</div>
<router-view :event="event" />
</div>
</template>
<script>
import EventService from '@/services/EventService.js'
export default {
props: ['id'],
data() {
return {
event: null
}
},
created() {
EventService.getEvent(this.id)
.then(response => {
this.event = response.data
})
.catch(error => {
console.log(error)
})
}
}
</script>
Notice
- This layout has the duplicate code from the 3 components we listed.
- 이 레이아웃에는 우리가 나열한 3개 구성 요소의 중복 코드가 있습니다.
- <router-view :event="event" /> is passing down the event object from our API.
- <router-view :event="event" />는 API에서 이벤트 객체를 전달합니다.
- Those components are quite simple like below.
- 해당 구성 요소는 아래와 같이 매우 간단합니다.
note) <router-view :event="event" /> 을 통하여 아래 Detail.vue, Register.vue, Edit.Vue 로 evant object 가 넘어간다.
/src/views/event/Details.vue
<template>
<p>{{ event.time }} on {{ event.date }} @ {{ event.location }}</p>
<p>{{ event.description }}</p>
</template>
<script>
export default {
props: ['event']
}
</script>
/src/views/event/Register.vue
<template>
<p>Register for the event here</p>
</template>
<script>
export default {
props: ['event']
}
</script>
/src/views/event/Edit.vue
<template>
<p>Edit the event here</p>
</template>
<script>
export default {
props: ['event']
}
</script>
/src/router/index.js
Mapping these Nested Routes together in our router file.
import { createRouter, createWebHistory } from 'vue-router'
import EventList from '../views/EventList.vue'
import EventLayout from '../views/event/Layout.vue'
import EventDetails from '../views/event/Details.vue'
import EventRegister from '../views/event/Register.vue'
import EventEdit from '../views/event/Edit.vue'
import About from '../views/About.vue'
const routes = [
{
path: '/',
name: 'EventList',
component: EventList,
props: route => ({ page: parseInt(route.query.page) || 1 })
},
{
path: '/event/:id',
name: 'EventLayout',
props: true,
component: EventLayout,
children: [ // <-----
{
path: '',
name: 'EventDetails',
component: EventDetails
},
{
path: 'register',
name: 'EventRegister',
component: EventRegister
},
{
path: 'edit',
name: 'EventEdit',
component: EventEdit
}
]
},
...
Notice
- The first is to notice our EventLayout route with the children option, which is sending in an another array of routes
- 첫 번째는 다른 경로 배열을 보내는, children 옵션이 있는 EventLayout 경로가 있는 것입니다.
- How the children are inheriting the path /event/:id from the parent route.
- 하위 항목이 상위 경로의 /event/:id 경로를 어떻게 상속하냐 하는 것이다.
- EventDetails has a blank path, this is what gets loaded into <router-view /> when /event/:id is visited.
- EventDetails에는 빈 경로가 있습니다. 이는 /event/:id를 방문할 때 <router-view />에 로드되는 경로입니다.
- /user/:id/register and /user/:id/edit simply load up the proper routes.
- /user/:id/register 및 /user/:id/edit는 단순히 적절한 경로를 로드합니다.
One more optimization
/src/views/event/Layout.vue (before optimization)
<template>
<div v-if="event">
<h1>{{ event.title }}</h1>
<div id="nav">
<router-link :to="{ name: 'EventDetails', params: { id } }"
>Details</router-link
>
|
<router-link :to="{ name: 'EventRegister', params: { id } }"
>Register</router-link
>
|
<router-link :to="{ name: 'EventEdit', params: { id } }"
>Edit</router-link
>
</div>
/src/views/event/Layout.vue (after optimization)
note) optimized code 에서는 params: { id } 없어져 있다
<template>
<div v-if="event">
<h1>{{ event.title }}</h1>
<div id="nav">
<router-link :to="{ name: 'EventDetails }"
>Details</router-link
>
|
<router-link :to="{ name: 'EventRegister' }"
>Register</router-link
>
|
<router-link :to="{ name: 'EventEdit' }"
>Edit</router-link
>
</div>
...
Since these links all require :id , when the router-link is rendered in the template (if it’s not sent in) it will look at the URL parameters, and if :id exists in the current route, it will use the :id in all of the link URLs.
이러한 링크에는 모두 :id가 필요하므로 router-link가 템플릿에서 렌더링된 경우(전송되지 않은 경우) URL 매개변수를 확인하고, :id가 현재 경로에 존재하는 경우 모든 링크 URL에서 :id를 사용한다.
Sample Codes
https://github.com/Code-Pop/Touring-Vue-Router/tree/L4-end
GitHub - Code-Pop/Touring-Vue-Router
Contribute to Code-Pop/Touring-Vue-Router development by creating an account on GitHub.
github.com
'Java Scripts > Vue.js' 카테고리의 다른 글
Vue : Global Component (0) | 2022.01.08 |
---|---|
Vue : Single File Component (0) | 2022.01.08 |
Vue : Dynamic Routing & History Mode (0) | 2022.01.08 |
Vue Router Basics (0) | 2021.12.31 |
Vue : Slots: Fundamentals (0) | 2021.12.31 |