Vue.js 의 공식 라우터로 페이지 간 이동을 위한 라이브러리 ➡️ 싱글 페이지 앱 (SPA)에 적합
페이지 이동할 때, url 변경되면, DOM 이 새로 갱신되는 것이 아니라 변경된 요소의 영역에 컴포넌트 갱신 ➡️ 싱글 페이지 앱(SPA)의 특징
설치 : npm install vue-router@4
<template>
<div id="app">
<nav>
<!-- 탐색을 위해 router-link 컴포넌트를 사용. -->
<!-- `to`라는 prop으로 링크를 지정. -->
<!-- `<router-link>`는 `href` 속성이 있는 `<a>` 태그로 렌더링됨. -->
<router-link to="/" class="nav-link" active-class="active-link"
>Home</router-link
>
<router-link to="/search" class="nav-link" active-class="active-link"
>Search</router-link
>
<router-link to="/about" class="nav-link" active-class="active-link"
>About</router-link
>
</nav>
<!-- 경로 출력 -->
<!-- 현재 경로에 매핑된 컴포넌트가 렌더링됨. -->
<router-view> </router-view>
<!-- <router-view /> -->
</div>
</template>
<script>
export default {};
</script>
<style>
nav {
display: flex;
/* justify-content: center; */
align-content: center;
}
.nav-link {
text-decoration: none;
color: black;
margin: 0 1rem;
padding: 1rem;
}
.active-link {
color: white; /* 또는 다른 원하는 스타일을 지정하세요 */
font-weight: bold;
background-color: orange;
}
</style>
: a
태그 대신 커스텀 컴포넌트인 router-link
를 사용하여 링크를 생성한다. 이를 통해 Vue Router는 페이지를 다시 로드하지 않고도 URL 변경, 생성 및 인코딩을 처리할 수 있다.
: URL에 해당하는 컴포넌트를 표시하고, 어디에나 배치 가능하여 레이아웃에 맞게 조정할 수 있다.
import { createApp } from "vue";
import { createRouter, createWebHistory } from "vue-router";
import App from "./App.vue";
import HomeRoute from "./routes/HomeRoute.vue";
import AboutRoute from "./routes/AboutRoute.vue";
import SearchRoute from "./routes/SearchRoute";
//1.
const routes = [
{ path: "/", component: HomeRoute },
{ path: "/about", component: AboutRoute },
{ path: "/search", component: SearchRoute },
];
//2.
const router = createRouter({
//3.
history: createWebHistory(),
routes,
});
//4.
const app = createApp(App);
app.use(router);
app.mount("#app");
⬆️ 작동 원리
⬆️ 출력 화면
파라미터 params
와 :
를 사용하여 구현 const User = {
template: '<div>사용자 {{ $route.params.id }}</div>',
}
// 이 경로들은 `createRouter`에 전달됨.
const routes = [
// 동적 세그먼트는 콜론으로 시작.
{ path: '/users/:id', component: User },
]
$route
객체의 수정을 감지할 수 있다. const User = {
template: '...',
created() {
this.$watch(
() => this.$route.params,
(toParams, previousParams) => {
// 경로 변경에 반응하기...
}
)
},
}
/user/johnny/profile /user/johnny/posts
+------------------+ +-----------------+
| User | | User |
| +--------------+ | | +-------------+ |
| | Profile | | +------------> | | Posts | |
| | | | | | | |
| +--------------+ | | +-------------+ |
+------------------+ +-----------------+
일부 앱의 UI는 여러 단계로 중첩된 컴포넌트로 구성된다. 위와같이 url 세그먼트가 중첩된 컴포넌트 중 특정 구조와 일치되고, 중첩된 경로 구성을 통해 구조적 관계를 구현할 수 있다.
<div id="app">
<router-view></router-view>
</div>
const User = {
template: `
<div class="user">
<h2>유저 {{ $route.params.id }}</h2>
<router-view></router-view>
</div>
`,
}
// 이것은 `createRouter`로 전달됨
const routes = [{ path: '/user/:id', component: User }]
<router-view>
는 최상위 router-view
로 일치하는 컴포넌트 안의 하위 컴포넌트에서도 <router-view>
를 포함할 수 있다. 이 중첩된 router-view
에 컴포넌트를 렌더링하려면, /user/:id
경로 내부의 모든 경로에 chilren
옵션을 사용해야한다.
const routes = [
{
path: '/user/:id',
component: User,
children: [
{
// /user/:id/profile 와 매치된 경우,
// User 컴포넌트 내부의 <router-view>에서 렌더링됨: UserProfile
path: 'profile',
component: UserProfile,
},
{
// /user/:id/posts 와 매치된 경우,
// User 컴포넌트 내부의 <router-view>에서 렌더링됨: UserPosts
path: 'posts',
component: UserPosts,
},
],
},
]
/
로 시작하는 중첩경로는 루트경로로 처리되고 이를 통해 중첩 URL를 사용하지 않고도 컴포넌트 중첩을 활용할 수 있다. chilren 옵션은 경로를 나타내는 배열로 필요한 만큼 중첩된 router-view 를 사용할 수 있다.
Vue 의 공식 라이브러리로 router-view 를 이용해 a 태그 없이 커스텀하게 쓰이는 것이 편리했다. main.js 와 app.vue 와 각각 라우팅에 맞는 컴포넌트들에 쓰이는 코드나 작동 원리를 이해하면서 라우팅에 대해 세세하게 깨달은 것 같다. 동적 라우팅은 파라미터나 쿼리 등 때문에 많이 쓰기도 해서 익숙했지만, 중첩 라우팅 같은 경우는 정말 필요한 경우가 종종 프로젝트 때 있었는데, children 옵션으로 간단히 설정할 수 있다는 점에서 놀라웠다.
출처
https://v3-docs.vuejs-korea.org/guide/scaling-up/routing.html#official-router
https://router.vuejs.kr/introduction.html