Vue Router
여러 페이지 사이를 자연스럽게 이동하는 방법을 배웁니다.
지금까지는 하나의 화면 안에서 여러 컴포넌트를 나누어 사용하는 방법을 배웠습니다.
하지만 실제 웹 프로그램은 보통 여러 화면으로 구성됩니다.
- 메인 화면
- 사원목록
- 사원등록
- 사원상세
- 게시판
- 로그인
여러 화면을 이동할 수 있도록 URL과 Vue 컴포넌트를 연결해 주는 기능입니다.
| 주소 | 화면 |
|---|---|
| / | 메인 화면 |
| /employees | 사원 목록 |
| /employees/new | 사원 등록 |
| /board | 게시판 |
일반적인 웹사이트에서는 페이지를 이동할 때 서버에 새로운 HTML 파일을 요청하는 방식이 많이 사용됩니다.
Vue에서는 하나의 애플리케이션 안에서 현재 URL에 따라 화면을 바꾸는 방식으로 구성할 수 있습니다.
Vue Router는 현재 주소를 확인한 후 어떤 화면 컴포넌트를 보여줄지 결정합니다.
이처럼 하나의 애플리케이션 안에서 화면을 전환하는 구조를 SPA(Single Page Application) 방식이라고 합니다.
Vue Router는 프로젝트에서 별도로 설치하여 사용합니다.
npm install vue-router
Vue 프로젝트 폴더의 터미널에서 명령어를 실행하면 됩니다.
보통 하나의 페이지 역할을 하는 컴포넌트는 views 폴더에 작성합니다.
| 폴더 | 역할 |
|---|---|
| components | 화면의 일부 |
| views | 하나의 페이지 |
하나의 View 안에서 여러 개의 작은 컴포넌트를 사용할 수도 있습니다.
<template>
<h1>사원관리 시스템</h1>
<p>
Vue 사원관리 프로그램입니다.
</p>
</template>
Vue 사원관리 프로그램입니다.
<script setup>
import { ref } from 'vue'
const employees = ref([
{
id: 1,
name: '홍길동',
department: '개발팀'
},
{
id: 2,
name: '김철수',
department: '영업팀'
},
{
id: 3,
name: '이영희',
department: '관리팀'
}
])
</script>
<template>
<h1>사원목록</h1>
<table border="1">
<thead>
<tr>
<th>번호</th>
<th>이름</th>
<th>부서</th>
</tr>
</thead>
<tbody>
<tr
v-for="emp in employees"
:key="emp.id"
>
<td>{{ emp.id }}</td>
<td>{{ emp.name }}</td>
<td>{{ emp.department }}</td>
</tr>
</tbody>
</table>
</template>
<script setup>
import { ref } from 'vue'
const name = ref('')
const department = ref('개발팀')
function saveEmployee() {
alert(
'이름 : ' + name.value +
'\n부서 : ' + department.value
)
}
</script>
<template>
<h1>사원등록</h1>
<p>
이름 :
<input v-model="name">
</p>
<p>
부서 :
<select v-model="department">
<option>개발팀</option>
<option>영업팀</option>
<option>관리팀</option>
</select>
</p>
<button @click="saveEmployee">
저장
</button>
</template>
이제 주소와 화면 컴포넌트를 연결합니다.
import {
createRouter,
createWebHistory
} from 'vue-router'
import HomeView
from '../views/HomeView.vue'
import EmployeeListView
from '../views/EmployeeListView.vue'
import EmployeeFormView
from '../views/EmployeeFormView.vue'
const routes = [
{
path: '/',
component: HomeView
},
{
path: '/employees',
component: EmployeeListView
},
{
path: '/employees/new',
component: EmployeeFormView
}
]
const router = createRouter({
history: createWebHistory(),
routes
})
export default router
routes 배열에서는 path와 component를 연결합니다.
Router를 만들었다면 Vue 애플리케이션에 연결해야 합니다.
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
createApp(App)
.use(router)
.mount('#app')
.use(router)가 있어야 Vue 애플리케이션에서 Router 기능을 사용할 수 있습니다.
현재 URL에 해당하는 화면을 표시할 위치에는 router-view를 사용합니다.
<template> <h1>사원관리 프로그램</h1> <router-view /> </template>
브라우저 주소가 /employees라면 EmployeeListView.vue가 router-view 위치에 표시됩니다.
사원관리 프로그램
┌─────────────────────┐
│ router-view │
│ │
│ 사원목록 화면 표시 │
└─────────────────────┘
Vue Router에서는 화면 이동 링크를 만들 때 보통 router-link를 사용합니다.
<router-link to="/"> 홈 </router-link> <router-link to="/employees"> 사원목록 </router-link> <router-link to="/employees/new"> 사원등록 </router-link>
<template>
<h1>사원관리 프로그램</h1>
<nav>
<router-link to="/">
홈
</router-link>
|
<router-link to="/employees">
사원목록
</router-link>
|
<router-link to="/employees/new">
사원등록
</router-link>
</nav>
<hr>
<router-view />
</template>
홈 | 사원목록 | 사원등록
현재 선택된 화면
↓
router-link
↓
/employees
↓
Vue Router
↓
EmployeeListView.vue
↓
router-view에 표시
Vue Router는 주소와 화면 컴포넌트를 연결합니다.
Route에는 path뿐 아니라 이름을 지정할 수도 있습니다.
{
path: '/employees',
name: 'employeeList',
component: EmployeeListView
}
const routes = [
{
path: '/',
name: 'home',
component: HomeView
},
{
path: '/employees',
name: 'employeeList',
component: EmployeeListView
},
{
path: '/employees/new',
name: 'employeeNew',
component: EmployeeFormView
}
]
Route에 이름을 지정해 두면 JavaScript에서 화면을 이동하거나 링크를 만들 때 활용할 수 있습니다.
버튼을 누른 후 다른 화면으로 이동해야 하는 경우에는 useRouter()를 사용할 수 있습니다.
<script setup>
import { ref } from 'vue'
import { useRouter } from 'vue-router'
const router = useRouter()
const name = ref('')
function saveEmployee() {
alert(
name.value + ' 사원을 저장했습니다.'
)
router.push('/employees')
}
</script>
<template>
<h1>사원등록</h1>
<input v-model="name">
<button @click="saveEmployee">
저장
</button>
</template>
↓
router.push()
↓
/employees
↓
사원목록 화면
router.push()에는 주소를 직접 넣을 수 있습니다.
router.push('/employees')
Route 이름을 이용하는 방법도 있습니다.
router.push({
name: 'employeeList'
})
두 방법 모두 같은 사원목록 화면으로 이동할 수 있습니다.
사원 한 명의 상세정보를 표시하려면 현재 어떤 사원을 선택했는지 구분해야 합니다.
/employees/2
/employees/3
Route에서는 다음과 같이 설정합니다.
{
path: '/employees/:id',
name: 'employeeDetail',
component: EmployeeDetailView
}
:id 부분은 주소에 따라 변경될 수 있는 값입니다.
/employees/10 → id = 10
현재 URL에 포함된 값을 가져올 때는 useRoute()를 사용할 수 있습니다.
<script setup>
import { useRoute } from 'vue-router'
const route = useRoute()
const employeeId = route.params.id
</script>
<template>
<h1>사원 상세정보</h1>
<p>
사원번호 : {{ employeeId }}
</p>
</template>
사원번호 : 10
사원목록의 이름을 클릭하면 각 사원의 상세화면으로 이동하도록 만들 수 있습니다.
<script setup>
import { ref } from 'vue'
const employees = ref([
{
id: 1,
name: '홍길동',
department: '개발팀'
},
{
id: 2,
name: '김철수',
department: '영업팀'
},
{
id: 3,
name: '이영희',
department: '관리팀'
}
])
</script>
<template>
<h1>사원목록</h1>
<table border="1">
<tr>
<th>번호</th>
<th>이름</th>
<th>부서</th>
</tr>
<tr
v-for="emp in employees"
:key="emp.id"
>
<td>
{{ emp.id }}
</td>
<td>
<router-link
:to="'/employees/' + emp.id"
>
{{ emp.name }}
</router-link>
</td>
<td>
{{ emp.department }}
</td>
</tr>
</table>
</template>
김철수 클릭 → /employees/2
router-link의 to에는 문자열 대신 객체 형태를 사용할 수도 있습니다.
<router-link
:to="{
name: 'employeeDetail',
params: {
id: emp.id
}
}"
>
{{ emp.name }}
</router-link>
이름을 이용해 화면을 연결하면 나중에 실제 URL 구조가 변경되었을 때 관리하기 편리할 수 있습니다.
import {
createRouter,
createWebHistory
} from 'vue-router'
import HomeView
from '../views/HomeView.vue'
import EmployeeListView
from '../views/EmployeeListView.vue'
import EmployeeFormView
from '../views/EmployeeFormView.vue'
import EmployeeDetailView
from '../views/EmployeeDetailView.vue'
const routes = [
{
path: '/',
name: 'home',
component: HomeView
},
{
path: '/employees',
name: 'employeeList',
component: EmployeeListView
},
{
path: '/employees/new',
name: 'employeeNew',
component: EmployeeFormView
},
{
path: '/employees/:id',
name: 'employeeDetail',
component: EmployeeDetailView
}
]
const router = createRouter({
history: createWebHistory(),
routes
})
export default router
<template>
<div>
<h1>
사원관리 시스템
</h1>
<nav>
<router-link to="/">
홈
</router-link>
|
<router-link to="/employees">
사원목록
</router-link>
|
<router-link to="/employees/new">
사원등록
</router-link>
</nav>
<hr>
<router-view />
</div>
</template>
┌────────┬──────────┬──────────┐
│ 홈 │ 사원목록 │ 사원등록 │
└────────┴──────────┴──────────┘
│
↓
Vue Router
│
┌────────┼────────┐
홈 목록 등록
│
사원 상세
사용자가 존재하지 않는 주소를 직접 입력하는 경우도 있습니다.
/abc /test /employees/aaa/bbb
이런 주소를 처리하기 위해 마지막에 다음 Route를 추가할 수 있습니다.
{
path: '/:pathMatch(.*)*',
component: NotFoundView
}
<template>
<h1>404</h1>
<p>
요청한 페이지를 찾을 수 없습니다.
</p>
<router-link to="/">
홈으로 이동
</router-link>
</template>
요청한 페이지를 찾을 수 없습니다.
홈으로 이동
| 구분 | router-link | router.push() |
|---|---|---|
| 사용 위치 | HTML 화면 | JavaScript 함수 |
| 형태 | 링크 | 프로그램 명령 |
| 사용 예 | 메뉴 이동 | 저장 후 이동 |
<router-link to="/employees"> 사원목록 </router-link>
router.push('/employees')
이름이 비슷하기 때문에 처음에는 혼동하기 쉽습니다.
| 기능 | 역할 | 대표 사용법 |
|---|---|---|
| useRoute() | 현재 주소 정보 읽기 | route.params.id |
| useRouter() | 다른 주소로 이동 | router.push() |
const route = useRoute() const id = route.params.id
const router = useRouter()
router.push('/employees')
useRoute() → 현재 주소 읽기
useRouter() → 다른 주소로 이동
Python Tkinter 프로그램에서는 여러 Frame으로 화면을 나누어 관리할 수 있습니다.
Vue에서는 페이지 역할을 하는 View 컴포넌트를 사용할 수 있습니다.
| 구분 | 화면 전환 방식 |
|---|---|
| Tkinter | 버튼 클릭 → Frame 변경 |
| Vue | 메뉴 클릭 → URL 변경 → Router → View 변경 |
버튼 클릭 → Frame 변경
Vue
메뉴 클릭 → URL 변경 → Router → View 변경
기존 Python 데스크톱 프로그램의 여러 화면을 웹 프로그램으로 옮길 때 Vue Router의 View 구조를 이해하면 화면 전환 방식을 파악하는 데 도움이 됩니다.
- Vue Router는 URL과 Vue 화면 컴포넌트를 연결하여 여러 화면을 이동할 수 있도록 관리합니다.
- 페이지 역할을 하는 컴포넌트는 보통 views 폴더에 작성합니다.
- Router를 사용하려면 프로젝트에 vue-router를 설치합니다.
- routes 배열에서는 path와 component를 연결합니다.
- Vue 애플리케이션에 Router를 연결할 때 .use(router)를 사용합니다.
- router-view는 현재 URL에 해당하는 화면이 표시되는 위치입니다.
- router-link는 메뉴나 링크를 이용해 화면을 이동할 때 사용합니다.
- router.push()는 JavaScript 함수에서 다른 화면으로 이동할 때 사용합니다.
- Route에 name을 지정하면 이름을 이용해서 화면 이동을 처리할 수 있습니다.
- /employees/:id와 같이 작성하면 URL에 동적으로 변경되는 값을 포함할 수 있습니다.
- useRoute()는 현재 주소와 URL 파라미터를 읽을 때 사용합니다.
- useRouter()는 다른 주소로 이동할 때 사용합니다.
- router-link는 화면의 링크, router.push()는 프로그램에서 실행하는 이동 명령이라고 생각하면 쉽습니다.
- 잘못된 주소는 /:pathMatch(.*)* Route를 이용해 404 화면으로 처리할 수 있습니다.
- Vue Router의 핵심 흐름은 URL 변경 → Router 확인 → View 선택 → router-view 표시입니다.