
네트워크에서 경로를 선택하는 프로세스
-> 웹 애플리케이션에서 다른 페이지 간의 전환과 경로를 관리하는 기술


-> 페이지는 1개이지만, 주소에 따라 여러 컴포넌트를 새로 렌더링하여 마치 여러 페이지를 사용하는 것처럼 보이도록 해야 함
Vue 공식 라우터
(The official Router for Vue.js)
Vite로 프로젝트 생성 시 Router 추가

서버 실행 후 Router로 인한 프로젝트 변화 확인
-> Home, About 링크에 따라 변경되는 URL과 새로 렌더링 되는 화면







※ 일반 컴포넌트와 구분하기 위해 컴포넌트 이름을 View로 끝나도록 작성하는 것을 권장
// index.js
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
routes: [
{
path: '/',
name: 'home',
component: HomeView
},
...
]
})
<!-- App.vue -->
<RouterLink :to="/">Home</RouterLink>
<RouterLink :to="/about">About</RouterLink>
<!-- App.vue -->
<RouterView />
경로에 이름을 지정하는 라우팅

URL의 일부를 변수로 사용하여 경로를 동적으로 매칭
-> 일정한 패턴의 URL 작성을 반복해야 함
<template>
<div>
<h1>UserView</h1>
</div>
</template>
// index.js
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
routes: [
{
path: '/user/:id',
name: 'user',
component: UserView,
},
]
})
-> UserView 컴포넌트로 이동하기 위한 RouterLink 작성
<!-- App.vue -->
<RouterLink :to="{ name: 'user', params: { 'id': userId } }">User</RouterLink>
<script setup>
import { ref } from 'vue'
const userId = ref(1)
</script>
-> 현재 사용자의 id를 출력하기
<!-- UserView.vue -->
<template>
<div>
<h1>UserView</h1>
<h2>{{ $route.params.id }}번 User 페이지</h2>
</div>
</template>
<!-- UserView.vue -->
<template>
<div>
<h1>UserView</h1>
<h2>{{ userId }}번 User 페이지</h2>
</div>
</template>
<script setup>
import { ref } from 'vue'
import { useRoute } from 'vue-router'
const route = useRoute()
const userId = ref(route.params.id)
</script>
중첩된 라우팅

-> component 폴더에 UserProfile, UserPosts 컴포넌트 작성
<!-- UserProfile.vue -->
<template>
<div>
<h1>UserProfile</h1>
</div>
</template>
<!-- UserPost.vue -->
<template>
<div>
<h1>UserPost</h1>
</div>
</template>
-> index.js에 두 컴포넌트를 import
// index.js
import UserPosts from '@/components/UserPosts.vue'
import UserProfile from '@/components/UserProfile.vue'
// index.js
{
path: '/user/:id',
name: 'user',
component: UserView,
children: [
// UserProfile은 UserView의 <RouterView> 내부에 렌더링
{ path: 'profile', name: 'user-profile', component: UserProfile },
// UserPost는 UserView의 <RouterView> 내부에 렌더링
{ path: 'posts', name: 'user-posts', component: UserPosts },
]
}
<!-- UserView.vue -->
<template>
<div>
<RouterLink :to="{ name: 'user-profile' }">Profile</RouterLink>
<RouterLink :to="{ name: 'user-posts' }">Posts</RouterLink>
<h1>UserView</h1>
<h2>{{ userId }}번 User 페이지</h2>
<hr>
<RouterView />
</div>
</template>

// index.js
{
path: '/user/:id',
// name: 'user',
component: UserView,
children: [
{ path: '', name: 'user', component: UserHome },
{ path: 'profile', name: 'user-profile', component: UserProfile },
{ path: 'posts', name: 'user-posts', component: UserPosts },
]
}
<!-- components/UserHome.vue -->
<template>
<div>
<h1>UserHome</h1>
</div>
</template>
<script setup>
</script>

RouterLink 대신 JavaScript를 사용해 페이지를 이동하는 것


<!-- UserView.vue -->
<button @click="goHome">홈으로</button>
<script setup>
import { useRoute, useRouter, onBeforeRouteLeave, onBeforeRouteUpdate } from 'vue-router';
const route = useRoute()
const userId = ref(route.params.id)
const router = useRouter()
const goHome = function () {
router.push({ name: 'home' })
}
</script>

<!-- UserView.vue -->
const goHome = function () {
router.replace({ name: 'home' })
}
Vue router를 통해 특정 URL에 접근할 때
다른 URL로 redirect를 하거나 취소하여 내비게이션을 보호
-> 라우트 전환 전/후 자동으로 실행되는 Hook
애플리케이션 전역에서 동작하는 가드
-> 작성위치: index.js
다른 URL로 이동하기 직전에 실행되는 함수
(Global Before Guards)
router.beforEach((to, from) => {
...
return false 또는 return { name: 'About' }
})
// index.js
router.beforeEach((to, from) => {
console.log(to)
console.log(from)
})
export default router
-> to에는 이동할 URL인 user 라우트에 대한 정보가,
from에는 현재 URL인 home 라우트에 대한 정보가 들어있음
<!-- LoginView.vue -->
<template>
<div>
<h1>LoginView</h1>
</div>
</template>
// index.js
import LoginView from '@/views/LoginView.vue'
{
path: '/login',
name: 'login',
component: LoginView,
}
<!-- App.vue -->
<RouterLink :to="{ name: 'login' }">Login</RouterLink>

// index.js
router.beforeEach((to, from) => {
const isAuthenticated = false
if (!isAuthenticated && to.name !== 'login') {
console.log('로그인이 필요합니다.')
return { name: 'login' }
}
})
특정 라우터에서만 동작하는 가드
-> 작성위치: index.js의 각 routes
특정 router에 진입했을 때만 실행되는 함수
-> 단순히 URL의 매개변수나 쿼리 값이 변경될 때는 실행되지 않고, 다른 URL에서 탐색해 올 때만 실행됨
{
path: '/user/:id',
name: 'user',
component: UserView,
beforeEnter: (to, from) => {
...,
return false
}
},
// index.js
{
path: '/user/:id',
component: UserView,
beforeEnter: (to, from) => {
console.log(to)
console.log(from)
}
},

-> 전역 가드 beforeEach 관련 코드는 주석 처리 후 진행
// index.js
{
path: '/login',
name: 'login',
component: LoginView,
beforeEnter: (to, from) => {
if (isAuthenticated === true) {
console.log('이미 로그인 상태입니다.')
return { name: 'home' }
}
}
},
...

특정 컴포넌트 내에서만 동작하는 가드
-> 작성위치: 각 컴포넌트의 <script> 내부
<!-- UserView.vue -->
import { onBeforeRouteLeave } from 'vue-router';
onBeforeRouteLeave((to, from) => {
const answer = window.confirm('정말 떠나실 건가요?')
if (answer === false) {
return false
}
})
-> 같은 라우트 내에서 업데이트 되는 경우 (/user/1 -> /user/100)

<!-- UserView.vue -->
<button @click="routeUpdate">100번 유저 페이지로</button>
<script setup>
const routeUpdate = function () {
router.push({ name: 'user', params: { id: 100 }})
}
onBeforeRouteUpdate((to, from) => {
userId.value = to.params.id
})
</script>