๋์ ๋ผ์ฐํธ ๋งค์นญ๊ณผ ํ๋ผ๋ฏธํฐ โ
์ข
์ข
์ฃผ์ด์ง ํจํด์ ๋ผ์ฐํธ๋ฅผ ๋์ผํ ์ปดํฌ๋ํธ์ ๋งคํํด์ผ ํ ๋๊ฐ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, ๋ชจ๋ ์ฌ์ฉ์์ ๋ํด ๋ ๋๋ง๋์ด์ผ ํ์ง๋ง ์๋ก ๋ค๋ฅธ ์ฌ์ฉ์ ID๋ฅผ ๊ฐ์ง User
์ปดํฌ๋ํธ๊ฐ ์์ ์ ์์ต๋๋ค. Vue Router์์๋ ๊ฒฝ๋ก์ ๋์ ์ธ๊ทธ๋จผํธ๋ฅผ ์ฌ์ฉํ์ฌ ์ด๋ฅผ ๋ฌ์ฑํ ์ ์์ผ๋ฉฐ, ์ด๋ฅผ _ํ๋ผ๋ฏธํฐ_๋ผ๊ณ ๋ถ๋ฆ
๋๋ค:
import User from './User.vue'
// ์ด๋ค์ `createRouter`์ ์ ๋ฌ๋ฉ๋๋ค
const routes = [
// ๋์ ์ธ๊ทธ๋จผํธ๋ ์ฝ๋ก ์ผ๋ก ์์ํฉ๋๋ค
{ path: '/users/:id', component: User },
]
์ด์ /users/johnny
์ /users/jolyne
์ ๊ฐ์ URL์ด ๋ชจ๋ ๋์ผํ ๋ผ์ฐํธ์ ๋งคํ๋ฉ๋๋ค.
_ํ๋ผ๋ฏธํฐ_๋ ์ฝ๋ก :
์ผ๋ก ํ์๋ฉ๋๋ค. ๋ผ์ฐํธ๊ฐ ๋งค์นญ๋๋ฉด, ํด๋น _ํ๋ผ๋ฏธํฐ_์ ๊ฐ์ ๋ชจ๋ ์ปดํฌ๋ํธ์์ route.params
๋ก ๋
ธ์ถ๋ฉ๋๋ค. ๋ฐ๋ผ์, User
์ ํ
ํ๋ฆฟ์ ๋ค์๊ณผ ๊ฐ์ด ์
๋ฐ์ดํธํ์ฌ ํ์ฌ ์ฌ์ฉ์ ID๋ฅผ ๋ ๋๋งํ ์ ์์ต๋๋ค:
<template>
<div>
<!-- ํ์ฌ ๋ผ์ฐํธ๋ ํ
ํ๋ฆฟ์์ $route๋ก ์ ๊ทผํ ์ ์์ต๋๋ค -->
User {{ $route.params.id }}
</div>
</template>
ํ๋์ ๋ผ์ฐํธ์ ์ฌ๋ฌ _ํ๋ผ๋ฏธํฐ_๋ฅผ ๊ฐ์ง ์ ์์ผ๋ฉฐ, ์ด๋ค์ route.params
์ ํด๋น ํ๋์ ๋งคํ๋ฉ๋๋ค. ์์:
ํจํด | ๋งค์นญ๋ ๊ฒฝ๋ก | route.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์ ์ฟผ๋ฆฌ๊ฐ ์์ ๊ฒฝ์ฐ), route.hash
๋ฑ๊ณผ ๊ฐ์ ์ ์ฉํ ์ ๋ณด๋ ์ ๊ณตํฉ๋๋ค. ์ ์ฒด ์ธ๋ถ ์ ๋ณด๋ API Reference์์ ํ์ธํ ์ ์์ต๋๋ค.
์ด ์์ ์ ๋์ํ๋ ๋ฐ๋ชจ๋ ์ฌ๊ธฐ์์ ํ์ธํ ์ ์์ต๋๋ค.
ํ๋ผ๋ฏธํฐ ๋ณ๊ฒฝ์ ๋ฐ์ํ๊ธฐ โ
ํ๋ผ๋ฏธํฐ๊ฐ ์๋ ๋ผ์ฐํธ๋ฅผ ์ฌ์ฉํ ๋ ์ฃผ์ํ ์ ์ ์ฌ์ฉ์๊ฐ /users/johnny
์์ /users/jolyne
์ผ๋ก ์ด๋ํ ๋, ๋์ผํ ์ปดํฌ๋ํธ ์ธ์คํด์ค๊ฐ ์ฌ์ฌ์ฉ๋๋ค๋ ๊ฒ์
๋๋ค. ๋ ๋ผ์ฐํธ ๋ชจ๋ ๋์ผํ ์ปดํฌ๋ํธ๋ฅผ ๋ ๋๋งํ๋ฏ๋ก, ์ด์ ์ธ์คํด์ค๋ฅผ ํ๊ดดํ๊ณ ์๋ก ์์ฑํ๋ ๊ฒ๋ณด๋ค ๋ ํจ์จ์ ์
๋๋ค. ํ์ง๋ง, ์ด๋ ์ปดํฌ๋ํธ์ ๋ผ์ดํ์ฌ์ดํด ํ
์ด ํธ์ถ๋์ง ์๋๋ค๋ ์๋ฏธ์ด๊ธฐ๋ ํฉ๋๋ค.
๋์ผํ ์ปดํฌ๋ํธ์์ ํ๋ผ๋ฏธํฐ ๋ณ๊ฒฝ์ ๋ฐ์ํ๋ ค๋ฉด, ์ด ์๋๋ฆฌ์ค์์๋ route.params
์ ๊ฐ์ด route
๊ฐ์ฒด์ ์ด๋ค ๊ฒ์ด๋ ๊ฐ์(watch)ํ๋ฉด ๋ฉ๋๋ค:
<script setup>
import { watch } from 'vue'
import { useRoute } from 'vue-router'
const route = useRoute()
watch(
() => route.params.id,
(newId, oldId) => {
// ๋ผ์ฐํธ ๋ณ๊ฒฝ์ ๋ฐ์...
}
)
</script>
<script>
export default {
created() {
this.$watch(
() => this.$route.params.id,
(newId, oldId) => {
// ๋ผ์ฐํธ ๋ณ๊ฒฝ์ ๋ฐ์...
}
)
},
}
</script>
๋๋, beforeRouteUpdate
๋ค๋น๊ฒ์ด์
๊ฐ๋๋ฅผ ์ฌ์ฉํ ์๋ ์์ผ๋ฉฐ, ์ด๋ฅผ ํตํด ๋ค๋น๊ฒ์ด์
์ ์ทจ์ํ ์๋ ์์ต๋๋ค:
<script setup>
import { onBeforeRouteUpdate } from 'vue-router'
// ...
onBeforeRouteUpdate(async (to, from) => {
// ๋ผ์ฐํธ ๋ณ๊ฒฝ์ ๋ฐ์...
userData.value = await fetchUser(to.params.id)
})
</script>
<script>
export default {
async beforeRouteUpdate(to, from) {
// ๋ผ์ฐํธ ๋ณ๊ฒฝ์ ๋ฐ์...
this.userData = await fetchUser(to.params.id)
},
// ...
}
</script>
๋ชจ๋ ๊ฒฝ๋ก/404 Not found ๋ผ์ฐํธ ์ก๊ธฐ โ
์ผ๋ฐ ํ๋ผ๋ฏธํฐ๋ /
๋ก ๊ตฌ๋ถ๋ URL ์กฐ๊ฐ ์ฌ์ด์ ๋ฌธ์๋ง ๋งค์นญํฉ๋๋ค. ๋ชจ๋ ๊ฒ์ ๋งค์นญํ๊ณ ์ถ๋ค๋ฉด, ํ๋ผ๋ฏธํฐ ๋ฐ๋ก ๋ค์ ๊ดํธ ์์ ์ ๊ท์์ ์ถ๊ฐํ์ฌ ์ปค์คํ
ํ๋ผ๋ฏธํฐ ์ ๊ท์์ ์ฌ์ฉํ ์ ์์ต๋๋ค:
const routes = [
// ๋ชจ๋ ๊ฒ์ ๋งค์นญํ๊ณ `route.params.pathMatch`์ ๋ฃ์ต๋๋ค
{ path: '/:pathMatch(.*)*', name: 'NotFound', component: NotFound },
// `/user-`๋ก ์์ํ๋ ๋ชจ๋ ๊ฒ์ ๋งค์นญํ๊ณ `route.params.afterUser`์ ๋ฃ์ต๋๋ค
{ path: '/user-:afterUser(.*)', component: UserGeneric },
]
์ด ํน์ ์๋๋ฆฌ์ค์์๋ ๊ดํธ ์์ ์ปค์คํ
์ ๊ท์์ ์ฌ์ฉํ๊ณ , pathMatch
ํ๋ผ๋ฏธํฐ๋ฅผ ์ ํ์ ์ผ๋ก ๋ฐ๋ณต ๊ฐ๋ฅํ๊ฒ ํ์ํ๊ณ ์์ต๋๋ค. ์ด๋ฅผ ํตํด ํ์ํ๋ค๋ฉด path
๋ฅผ ๋ฐฐ์ด๋ก ๋ถํ ํ์ฌ ํด๋น ๋ผ์ฐํธ๋ก ์ง์ ์ด๋ํ ์ ์์ต๋๋ค:
router.push({
name: 'NotFound',
// ํ์ฌ ๊ฒฝ๋ก๋ฅผ ์ ์งํ๊ณ , ๋์ URL์ด `//`๋ก ์์ํ์ง ์๋๋ก ์ฒซ ๊ธ์๋ฅผ ์ ๊ฑฐ
params: { pathMatch: route.path.substring(1).split('/') },
// ๊ธฐ์กด ์ฟผ๋ฆฌ์ ํด์๊ฐ ์๋ค๋ฉด ์ ์ง
query: route.query,
hash: route.hash,
})
์์ธํ ๋ด์ฉ์ ๋ฐ๋ณต ํ๋ผ๋ฏธํฐ ์น์ ์ ์ฐธ๊ณ ํ์ธ์.
History ๋ชจ๋๋ฅผ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ, ์๋ฒ๋ฅผ ์ฌ๋ฐ๋ฅด๊ฒ ๊ตฌ์ฑํ๊ธฐ ์ํ ์ง์นจ๋ ๋ฐ๋์ ๋ฐ๋ผ์ผ ํฉ๋๋ค.
๊ณ ๊ธ ๋งค์นญ ํจํด โ
Vue Router๋ express
์์ ์๊ฐ์ ๋ฐ์ ์์ฒด ๊ฒฝ๋ก ๋งค์นญ ๋ฌธ๋ฒ์ ์ฌ์ฉํ๋ฏ๋ก, ์ ํ์ ํ๋ผ๋ฏธํฐ, 0๊ฐ ์ด์/1๊ฐ ์ด์์ ์๊ตฌ์ฌํญ, ์ฌ์ง์ด ์ปค์คํ
์ ๊ท์ ํจํด๊ณผ ๊ฐ์ ๋ค์ํ ๊ณ ๊ธ ๋งค์นญ ํจํด์ ์ง์ํฉ๋๋ค. ์์ธํ ๋ด์ฉ์ ๊ณ ๊ธ ๋งค์นญ ๋ฌธ์๋ฅผ ์ฐธ๊ณ ํ์ธ์.