[TIL] Vue - Routing

jeongjwon·2024년 1월 10일
0

Vue

목록 보기
9/19

Vue Router

  • Vue.js 의 공식 라우터로 페이지 간 이동을 위한 라이브러리 ➡️ 싱글 페이지 앱 (SPA)에 적합

  • 페이지 이동할 때, url 변경되면, DOM 이 새로 갱신되는 것이 아니라 변경된 요소의 영역에 컴포넌트 갱신 ➡️ 싱글 페이지 앱(SPA)의 특징

  • 설치 : npm install vue-router@4






예제

App.vue

<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 변경, 생성 및 인코딩을 처리할 수 있다.

  • router-view

    : URL에 해당하는 컴포넌트를 표시하고, 어디에나 배치 가능하여 레이아웃에 맞게 조정할 수 있다.




main.js

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");
  1. 경로를 정의하고, 각 경로를 컴포넌트와 매핑.
  2. 'routes'를 옵션으로 전달해 라우터 인스턴스 생성
  3. 사용할 히스토리 모드 정의. 이 예제에서는 간단하게 해시 모드 사용
  4. 루트 인스턴스를 생성하고 마운트.


⬆️ 파일 경로


⬆️ 작동 원리


⬆️ 출력 화면











동적 경로 매칭 Dynamic Routing

  • 주어진 경로의 패턴에 해당하는 컴포넌트를 매핑해야할 경우의 라우팅
  • 동적 세그먼트인 파라미터 params: 를 사용하여 구현
	const User = {
  	template: '<div>사용자 {{ $route.params.id }}</div>',
	}

	// 이 경로들은 `createRouter`에 전달됨.
	const routes = [
  	// 동적 세그먼트는 콜론으로 시작.
  		{ path: '/users/:id', component: User },
	]
  • 동일한 컴포넌트를 재사용하여 컴포넌트의 lifecycle hook이 호출되지 않기 때문에 params 의 변경사항에 반응하기 위해서는 watch 옵션으로 $route 객체의 수정을 감지할 수 있다.
	const User = {
  		template: '...',
  		created() {
    		this.$watch(
      			() => this.$route.params,
      			(toParams, previousParams) => {
        		// 경로 변경에 반응하기...
      			}
    		)
  		},
	}










중첩된 경로 Nested Routers

/user/johnny/profile                     /user/johnny/posts
+------------------+                  +-----------------+
| User             |                  | User            |
| +--------------+ |                  | +-------------+ |
| | Profile      | |  +------------>  | | Posts       | |
| |              | |                  | |             | |
| +--------------+ |                  | +-------------+ |
+------------------+                  +-----------------+

일부 앱의 UI는 여러 단계로 중첩된 컴포넌트로 구성된다. 위와같이 url 세그먼트가 중첩된 컴포넌트 중 특정 구조와 일치되고, 중첩된 경로 구성을 통해 구조적 관계를 구현할 수 있다.

  • 라우터 컴포넌트 안에 하위 라우터 컴포넌트를 중첩하여 구성하는 방식
  • 라우터로 설정에서 chilren 옵션 사용
<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

0개의 댓글