'Vue 기본기 다지기 4편'에서는
ref,
reactive,
computed,
watch를 통해 컴포넌트의 상태를 반응적으로 관리하는 방법을 익혔습니다.
이를 통해 우리는 동적인 데이터를 다룰 수 있는 힘을 갖게 되었습니다.
이번 시간에는 사용자가 여러 페이지를 오가는 듯한 경험을 제공하는
싱글 페이지 애플리케이션(Single Page Application, SPA)
을 만드는 방법을 알아보겠습니다.
SPA는 최초 한 번만 전체 페이지를 불러오고, 그 후에는 필요한 데이터만 서버에서 받아와 화면을 동적으로 다시 그리는 방식입니다.
이러한 SPA의 페이지 전환을 관리해 주는 공식 라이브러리가 바로
Vue Router
입니다.
먼저 우리 프로젝트에 Vue Router를 설치해야 합니다.
터미널에서 아래 명령어를 실행해 주세요.
설치가 완료되면, 라우팅 관련 설정을 한곳에서 관리하기 위해 src 폴더 아래에 router라는 폴더를 만들고, 그 안에 index.js 파일을 생성하는 것이 일반적입니다.
이 파일에서 어떤 주소(URL)로 접속했을 때 어떤 컴포넌트를 보여줄지 정의합니다.
src/router/index.js import { createRouter, createWebHistory } from 'vue-router'
import HomeView from '../views/HomeView.vue'
import AboutView from '../views/AboutView.vue'
// 1. 각 URL 경로에 보여줄 컴포넌트들을 정의합니다.
const routes = [
{
path: '/' ,
name: 'home' ,
component: HomeView
},
{
path: '/about' ,
name: 'about' ,
component: AboutView
}
]
// 2. 라우터 인스턴스를 생성합니다.
const router = createRouter ({
history: createWebHistory (), // HTML5 History API를 사용합니다.
routes, // `routes: routes` 와 동일합니다.
})
// 3. 라우터 인스턴스를 내보냅니다.
export default router
여기서 createWebHistory는 브라우저의 History API를 사용하여 주소창에 # 기호 없이 깔끔한 URL(http://localhost:5173/about)을 만들어 줍니다.
이제 우리가 만든 라우터 설정을 Vue 앱 전체가 알 수 있도록 main.js 파일에 등록해야 합니다.
src/main.js import { createApp } from 'vue'
import App from './App.vue'
import router from './router' // 방금 만든 router/index.js 파일을 가져옵니다.
const app = createApp (App)
app. use (router) // Vue 앱에 라우터를 사용하겠다고 알려줍니다.
app. mount ( '#app' )
이것으로 기본적인 설정은 모두 끝났습니다.
라우터를 설정했으니, 이제 사용자가 누를 수 있는 링크와, 주소에 따라 바뀔 화면 영역을 만들어야 합니다.
<router-link> 와 <router-view> 🔗
<router-link>
페이지를 새로고침하지 않고 주소를 변경하는 링크를 만들 때 사용합니다.
<a> 태그로 렌더링되지만, SPA의 특성을 유지해 줍니다. to 속성을 이용해 이동할 경로를 지정합니다.
<router-view>
현재 URL 경로에 맞는 컴포넌트가 렌더링되는 '자리표시자' 역할을 합니다.
즉, 이 컴포넌트가 있는 위치에 HomeView나 AboutView 등이 보이게 됩니다.
App.vue 파일을 수정하여 모든 페이지에 공통으로 보일 내비게이션 바와 콘텐츠 영역을 만들어 보겠습니다.
src/App.vue < template >
< header >
< nav >
< router-link to = "/" >Home</ router-link > |
< router-link to = "/about" >About</ router-link >
</ nav >
</ header >
< main >
< router-view />
</ main >
</ template >
< style >
nav {
padding : 20 px ;
text-align : center ;
}
nav a {
font-weight : bold ;
color : #2c3e50 ;
}
nav a .router-link-exact-active {
color : #42b983 ; /* 현재 활성화된 링크 스타일 */
}
</ style >
이제 브라우저에서 Home과 About 링크를 클릭해 보세요.
페이지 전체가 새로고침되지 않고
<main> 영역의 콘텐츠만 부드럽게 바뀌는 것을 확인할 수 있습니다.
블로그 게시물이나 사용자 프로필 페이지처럼, 같은 구조를 가지지만 내용만 다른 여러 페이지가 필요할 때가 있습니다.
이럴 때
동적 라우팅
을 사용합니다.
예를 들어,
/users/1,
/users/2 와 같이 주소의 일부를 변수처럼 사용하는 것입니다.
경로에 :(콜론)을 사용하여 파라미터를 받을 수 있음을 표시합니다.
src/router/index.js // ... 기존 코드 ...
import UserView from '../views/UserView.vue'
const routes = [
// ... Home, About 라우트 ...
{
// :id 부분이 동적으로 변경되는 파라미터입니다.
path: '/users/:id' ,
name: 'user' ,
component: UserView
}
]
// ...
이제
UserView 컴포넌트에서는 현재 URL에서
:id 값을 어떻게 가져와 사용할 수 있을까요.
Composition API에서는
useRoute 훅을 사용합니다.
src/views/UserView.vue < script setup >
import { useRoute } from 'vue-router'
import { ref, onMounted } from 'vue'
// useRoute()를 호출하여 현재 라우트 정보를 가져옵니다.
const route = useRoute ()
// route.params 객체에서 동적 파라미터 'id'를 가져옵니다.
const userId = ref (route.params.id)
onMounted (() => {
// 컴포넌트가 마운트되면 콘솔에 사용자 ID를 출력합니다.
// 실제 앱에서는 이 ID로 사용자 정보를 서버에 요청할 수 있습니다.
console. log ( `이 사용자의 ID는 ${ userId . value } 입니다.` );
})
</ script >
< template >
< div >
< h2 >사용자 프로필 페이지</ h2 >
< p >사용자 ID: {{ userId }}</ p >
</ div >
</ template >
이제 브라우저 주소창에 /users/100 이라고 입력하면, 화면에 "사용자 ID: 100"이 표시될 것입니다.
사용자가 존재하지 않는 주소로 접속했을 때, "페이지를 찾을 수 없습니다"와 같은 안내를 보여주는 것은 좋은 사용자 경험을 위해 필수적입니다.
Vue Router에서는 정규 표현식을 사용해 모든 경로와 일치하는 '캐치올(catch-all)' 라우트를 만들어 404 페이지를 구현할 수 있습니다.
src/views/NotFoundView.vue < template >
< div >
< h1 >404 Not Found</ h1 >
< p >요청하신 페이지를 찾을 수 없습니다.</ p >
< router-link to = "/" >홈으로 돌아가기</ router-link >
</ div >
</ template >
👨💻
이 라우트는 반드시 'routes' 배열의 가장 마지막에 위치해야 합니다.
그래야 다른 모든 경로를 확인한 후, 일치하는 것이 없을 때 마지막으로 이 라우트가 선택됩니다.
src/router/index.js // ... 기존 코드 ...
import NotFoundView from '../views/NotFoundView.vue'
const routes = [
// ... Home, About, User 라우트 ...
// 정의된 다른 경로와 일치하지 않는 모든 경로를 잡습니다.
{
path: '/:pathMatch(.*)*' ,
name: 'NotFound' ,
component: NotFoundView
},
]
// ...
이제 존재하지 않는 주소(예: /random-page)로 접속하면 우리가 만든 404 페이지가 나타납니다.
이번 시간에는 Vue Router를 사용하여 여러 페이지를 가진 SPA를 만드는 기본 방법을 알아보았습니다.
Vue Router는 이 외에도 중첩 라우팅, 내비게이션 가드 등 강력한 기능들을 많이 제공합니다.
하지만 오늘 배운 내용만으로도 충분히 기본적인 멀티 페이지 애플리케이션을 구성할 수 있을 것입니다.
다음 'Vue 기본기 다지기 6편'에서는 여러 컴포넌트가 함께 사용하는 데이터를 효율적으로 관리하는 '전역 상태 관리' 라이브러리, Pinia에 대해 알아보겠습니다.