SPA는 서버에 요청 시마다 웹 페이지를 새로 받아오지 않고 최초의 요청에서 전체를 받아온 후 보이는 컴포넌트만 교체하는 형식이다. 따라서 기본적으로 한 페이지이기 때문에 페이지 이동이라는 개념이 없다. 단지 컴포넌트의 교체만 존재할 뿐이다. router란 컴포넌트를 교체하면서 마치 페이지가 이동하는 것처럼 만들어주는 역할을 수행하는 라이브러리다.
만약 vue router가 없이 생성된 프로젝트에 vue router를 추가하려면 아래와 같이 추가할 수 있다.
npm install vue-router // npm을 이용한 라이브러리 설치 방식
하지만 위와 같이 npm install로 라이브러리를 추가한 경우는 main.js에서 reouter를 등록하는 코드나 src/router/index.js 코드가 자동 삽입되지 않기 때문에 별도로 추가해주어야 한다.
기존의 vue cli에서는 vue 명령을 통해 router를 설치할 수 있었고 이 경우 템플릿을 만들어줬는데 vite에서는 그런 기능이 없는 것 같다.(vite는 vue 전용이 아니니까 당연한 것 같기는 하다.) 혹시 vite에서 vue plugin 설치 방법을 아시는 분 알려주세요!!
기본 구조
먼저 <template> 영역에서 vue router를 사용하기 위해서는 두 개의 간단한 태그가 사용된다. 이 태그는 기본 내장 컴포넌트를 사용하기 때문에 컴포넌트 형태로 사용해도 무방하다.
먼저 이동 대상인 자식 view 들을 준비하자. 느닷없이 view가 나왔는데 사실은 이제까지 봤던 자식 component와 동일한 녀석이다. 특별히 view라고 구분하는 이유는 일반적으로 component는 부품으로 재사용되는 것들을 모두 이야기하는 것이고 component 중 router를 통해 이동하는 대상 즉 페이지의 개념으로 사용되는 component를 view로 분류한다.
/src/views/ 아래에 페이지로 사용할 EmptyView, SubPage1View, SubPage2View를 만들어보자.
<!-- src/views/EmptyView.vue --><template><div></div></template><!-- src/views/SubPage1View.vue--><template><h2>여기는 sub page 1</h2></template><!-- src/views/SubPage2View.vue--><template><h2>여기는 sub page 2</h2></template>
src/router/index.js
이제router에서 컴포넌트와 경로를 매핑시켜 보자. 만들어진 기본 템플릿에 필요한 내용만 작성해 주면 되니 큰 어려움은 없을 것이다.
<template>에서는 앞서 언급한 <RouterLink>와 <RouterView>를 이용해서 페이지 이동 링크와 하위 컴포넌트 표시 영역을 지정한다. <RouterLink>에는 to 속성을 이용해서 이동 대상 경로를 지정한다. 경로는 절대경로와 상태경로 모두 사용 가능하다.
<script setup></script>
<template><header><divclass="wrapper"><h1>페이지 이동 테스트</h1><nav><RouterLinkto="/">기본페이지</RouterLink><RouterLinkto="/sub1">절대경로: SubPage1View로 이동</RouterLink><RouterLinkto="./sub2">상대경로: SubPage2View로 이동</RouterLink></nav></div></header><!-- router의 url에 따라 갱신되는 영역 --><RouterView /></template><stylescoped></style>
RouterLink나 RouterView는 모두 vue-router에 포함된 내장 컴포넌트이다. 따라서 router-link, router-view라고 사용하기도 한다.
개발자 도구 확인
개발자 도구를 통해서도 Vue-Router의 구성을 손쉽게 파악할 수 있다.
다양한 경로 활용
프로그래밍 방식 활용
위 예에서는 간단히 링크를 통한 페이지 이동에 대해 살펴봤는데 실제 개발을 하다 보면 프로그래밍적으로 페이지 이동을 처리해야 하는 경우가 많다. 이때는vue-router가 제공하는 useRouter라는 함수를 통해 router 객체를 얻은 후push메서드를 이용해 이동할 경로를 전달해 주면 된다. 경로는 path 기반일 경우는 path, 이름 기반일 경우는 name 속성을 갖는 객체를 전달한다. 단 path의 경우는 그냥 path만 전달할 수도 있다.
대음은 moveTo라는 함수에 path가 전달될 때 그 경로로 이동하는 코드이다.
import { useRouter } from'vue-router'const router = useRouter()
constmoveTo = (target) => {
router.push({ path:target }) // path 기반일 경우: 객체 형태로 전달// router.push(target) // path 기반일 경우: 경로만 전달 가능// router.push({ name:target }) // name 기반일 경우// router.replace({ name:target }) // name 기반일 경우: 경로 대체
}
push의 경우 이동 history에서 경로를 stack 개념으로 관리한다. 따라서 뒤로 가기 기능이 가능하다. A -> login -> (push)B에서 뒤로가기를 했다면 다시 login으로 이동한다. 이미 로그인 된 상태에서 대략 난감이다.
이런 경우는 replace 메서드를 사용한다. replace를 사용하면 현재 경로를 대체한다. 따라서 A -> login ->(replace)B로 이동했을 때 B에서 뒤로가기를 하면 A로 대체된다. 만약 RouterLink를 이용하려는 경우 뒤에 replace라고 추가해주면 된다.
<RouterLinkto="/user"replace>User</RouterLink>
v-bind:to
to는 단순히 RouterLink에 선언된 속성이기 때문에 v-bind 속성을 이용해서 값을 매핑시키는 것도 물론 가능하다.