Vue에서 라우팅을 간편하게 할 수 있도록 도와주는 라이브러리
vue-router
패키지를 설치한 뒤, 아래처럼 createRouter()
함수를 통해 라우팅 설정을 할 수 있다.
router
import { createRouter, <mode> } from 'vue-router';
import Home from './Home';
import About from './About';
import NotFound from './NotFound';
export default createRouter({
history: <mode>,
routes: [
{
path: '/',
component: Home
},
{
path: '/about',
component: About
},
{
path: '/:notFound(.*)',
component: NotFound
}
]
});
역시나 바로 사용할 수는 없고, app.use()
메서드를 통해 등록해야 한다.
main
import { createApp } from 'vue';
import App from './App.vue';
import router from '~/routes';
const app = createApp(App);
app.use(router);
app.mount('#app');
등록까지 완료됐다면, 전역 컴포넌트인 RouterLink
와 RouterView
를 사용할 수 있다.
RouterLink
컴포넌트는 to
속성을 통해 이동할 경로를 설정할 수 있으며, RouterLink
의 content
를 누르면 해당 경로로 이동한다. RouterLink
내부의 엘리먼트는 anchor
태그로 래핑된다는 것에 유의하자.
RouterView
컴포넌트는 해당 경로에 설정된 컴포넌트를 출력해주는 역할을 한다.
<template>
<RouterLink to="/">
<button>Home</button>
</RouterLink>
<RouterLink to="/about">
<button>About</button>
</RouterLink>
<RouterView />
</template>
Home
버튼과 About
버튼을 누르면 각각 /
과 /about
으로 이동하며, 해당 경로에 설정된
컴포넌트가 RouterView
위치에 출력되게 된다.
이 외에도 컴포넌트 내부에서 페이지의 정보를 가지고 있는 $route
, 페이지를 제어할 때 사용하는 $router
전역 객체도 사용이 가능하다.
아래는 $router
객체를 이용해서 RouterLink
를 사용하지 않고 페이지 경로를 변경하는 예제다.
<template>
<button @click="$router.push('/')">
Home
</button>
<button @click="$router.push('/about')">
About
</button>
<RouterView />
</template>
path
를 정의할 때 :(Colon)
기호를 이용해서 동적 경로에 대한 설정도 가능하다.
import { createRouter, createWebHashHistory } from 'vue-router';
import Home from './Home';
import About from './About';
import DocsId from './DocsId';
import NotFound from './NotFound';
export default createRouter({
history: createWebHashHistory(),
routes: [
{
path: '/',
component: Home
},
{
path: '/about',
component: About
},
{
path: '/documents/:id',
component: DocsId
},
{
path: '/:notFound(.*)',
component: NotFound
}
]
});
이 외에도, 아래처럼 children
프로퍼티를 이용해서 하위 경로도 설정할 수 있다.
다만 주의해야 할 점은 children
에서 path
는 상대적인 경로를 지정해야 하며, 상위 경로에 해당하는 컴포넌트 내부에서 RouterView
컴포넌트를 이용해서 출력해야 한다는 것이다.
router
import { createRouter, createWebHashHistory } from 'vue-router';
import Home from './Home';
import About from './About';
import Docs from './Docs';
import DocsId from './DocsId';
import NotFound from './NotFound';
export default createRouter({
history: createWebHashHistory(),
routes: [
{
path: '/',
component: Home
},
{
path: '/about',
component: About
},
{
path: '/documents',
component: Docs,
children: [
{
path: ':id',
component: DocsId
}
]
},
{
path: '/:notFound(.*)',
component: NotFound
}
]
});
Docs
<template>
<h1>Docs.vue</h1>
<RouterView />
</template>
다만 이렇게 children
을 사용하게 되면 Docs
컴포넌트의 내용도 같이 출력되게 되므로, 이런 동작을 원하지 않는다면 분리해서 사용하도록 하자.
필요에 따라 경로 설정에 name
프로퍼티를 이용해서 이름을 정의할 수 있다.
이름을 지정해준 경우 이름을 통해 해당 경로로 이동이 가능해지며, queryString
과 parameter
가 필요한 경우 객체 형태로 값을 넘겨줄 수 있다.
router
import { createRouter, createWebHashHistory } from 'vue-router';
import Home from './Home';
import DocsId from './DocsId';
import NotFound from './NotFound';
export default createRouter({
history: createWebHashHistory(),
routes: [
{
path: '/',
component: Home
},
{
path: '/documents/:id',
name: 'docsId',
component: DocsId
},
{
path: '/:notFound(.*)',
component: NotFound
}
]
});
App
<template>
<button @click="$router.push('/')">
Home
</button>
<button
@click="$router.push({
name: 'docsId',
params: { id: 7777 }
})">
DocsId
</button>
<RouterView />
</template>
URL을 변경하는 과정에서 해당 페이지에 대한 접근을 차단할 때 사용하는 기능
vue-router
의 createRouter()
메서드가 반환한 router
객체에 네비게이션 가드 메서드가 존재한다.
네비게이션 가드의 실행 순서는 간략하게 추리면 아래와 같다.
- Global Before Guards
- In-Component Guards
- Global Resolve Guards
- Global After Hooks
새로운 네비게이션을 시작할 때 이 메서드의 콜백이 실행된다.
기본적인 문법은 아래와 같다.
import router from './index';
router.beforeEach((to [, from] [, next]) => {
...
});
to
는 이동하려는 페이지의 정보를 가지고 있으며, from
은 현재 페이지의 정보를 가지고 있다.
next
는 vue-router 3.x
버전에서 return
키워드 대신 사용하던 메서드이다.
네비게이션이 최종적으로 승인되기 직전에 실행된다.
실행 순서를 제외하면 beforeEach()
와 동일하다.
네비게이션이 승인된 후 호출되는 함수
기본적인 문법은 아래와 같다.
import router from './index';
router.afterEach((to [, from] [, failure]) => {
...
});
failure
는 네비게이션이 실패했음을 알리는 객체이며, 실패하지 않았다면 falsy
값을 반환한다.
이렇게 전역으로 동작하는 가드 외에도 라우터 가드와 컴포넌트 가드도 있다.
자세한 내용은 Navigation Guards | Vue Router를 참고하자.
라우터 객체 내부에 scrollBehavior()
메서드를 이용해서 스크롤 위치를 제어할 수 있다.
import { createRouter, createWebHistory } from 'vue-router';
import Home from './Home';
import About from './About';
export default createRouter({
history: createWebHistory(),
routes: [
{
path: '/',
component: Home
},
{
path: '/about',
component: About
}
],
scrollBehavior() {
return {
top: 0
};
}
});
이 외에도 아래처럼 각종 프로퍼티와 매개변수를 이용해서 다양한 동작이 가능하다.
scrollBehavior([to] [, from] [, savedPosition]) {
return {
el: '<selector>',
behavior: 'smooth | auto(default)'
}
}
to
와 from
은 네비게이션과 동일하며, savedPosition
은 popstate
이벤트가 발생했을 때 스크롤 정보를 가지고 있다.
또한 scrollBehavior
의 반환값으로 Promise
를 이용해서 비동기 스크롤도 구현이 가능하다.