'Vue 기본기 다지기 4편'에서는
ref
,
reactive
,
computed
,
watch
를 통해 컴포넌트의 상태를 반응적으로 관리하는 방법을 익혔습니다.
이를 통해 우리는 동적인 데이터를 다룰 수 있는 힘을 갖게 되었습니다.
이번 시간에는 사용자가 여러 페이지를 오가는 듯한 경험을 제공하는
싱글 페이지 애플리케이션(Single Page Application, SPA)
을 만드는 방법을 알아보겠습니다.
SPA는 최초 한 번만 전체 페이지를 불러오고, 그 후에는 필요한 데이터만 서버에서 받아와 화면을 동적으로 다시 그리는 방식입니다.
이러한 SPA의 페이지 전환을 관리해 주는 공식 라이브러리가 바로
Vue Router
입니다.
🚀
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에 대해 알아보겠습니다.