Post

10장 vue-router

10장 vue-router

10장 vue-router를 이용한 라우팅

10.1 vue-router란?

vue-router는 Vue.js에서 페이지 간 이동을 관리하는 공식 라우팅 라이브러리입니다. 바이트로 깔면 일일이 다 설치해줘야됨. 특히 main.js 에 app.use(‘router”) 인가 안썼다고 두시간 날렸음

10.2 vue-router의 기본 사용법

1
2
3
4
5
6
<!-- main.js -->
import { createRouter, createWebHistory } from 'vue-router'
const router = createRouter({
  history: createWebHistory(),
  routes: [{ path: '/', component: () => import('./Home.vue') }]
})

vue-router를 설정해 기본 라우팅을 시작합니다.

10.3 router 객체와 currentRoute 객체

1
2
3
4
5
6
<script setup>
import { useRouter, useRoute } from 'vue-router'
const router = useRouter()
const route = useRoute()
console.log(route.path) // 현재 경로
</script>

useRouteruseRoute로 라우팅 정보에 접근합니다.

10.4 동적 라우트

1
2
3
4
5
6
<!-- router/index.js -->
const routes = [{ path: '/user/:id', component: () => import('./User.vue') }]
<!-- User.vue -->
<template>
  <p>User ID: </p>
</template>

동적 라우트는 URL 파라미터로 유연한 경로를 처리합니다.

10.5 중첩 라우트

1
2
3
4
5
6
<!-- router/index.js -->
const routes = [{
  path: '/parent',
  component: () => import('./Parent.vue'),
  children: [{ path: 'child', component: () => import('./Child.vue') }]
}]

중첩 라우트는 계층적 페이지 구조를 만듭니다.

Vue Router에서의 중첩 라우트(Nested Routes) 설명

Vue Router의 중첩 라우트는 URL 경로의 세그먼트와 애플리케이션 UI의 중첩된 구조를 일치시키는 방법입니다. 예를 들어 사용자 프로필 페이지에서 다양한 하위 섹션(게시물, 팔로워, 정보 등)을 가지고 있을 때 유용합니다.

기본 개념

중첩 라우트를 사용하면:

  • URL의 계층 구조와 컴포넌트의 계층 구조를 일치시킬 수 있습니다
  • 부모 컴포넌트가 유지된 상태에서 자식 컴포넌트만 변경할 수 있습니다

예시 코드

1. 라우터 설정

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import { createRouter, createWebHistory } from 'vue-router'
import UserLayout from './views/UserLayout.vue'
import UserProfile from './views/UserProfile.vue'
import UserPosts from './views/UserPosts.vue'
import UserFollowers from './views/UserFollowers.vue'

const routes = [
  {
    path: '/user/:id',
    component: UserLayout,
    children: [
      // UserLayout 내부의 <router-view>에 렌더링됨
      { path: '', component: UserProfile }, // /user/:id
      { path: 'posts', component: UserPosts }, // /user/:id/posts
      { path: 'followers', component: UserFollowers } // /user/:id/followers
    ]
  }
]

const router = createRouter({
  history: createWebHistory(),
  routes
})

export default router

2. 부모 컴포넌트 (UserLayout.vue)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<template>
  <div class="user-container">
    <header>
      <h1>사용자 </h1>
      <nav>
        <router-link :to="`/user/${$route.params.id}`">프로필</router-link>
        <router-link :to="`/user/${$route.params.id}/posts`">게시물</router-link>
        <router-link :to="`/user/${$route.params.id}/followers`">팔로워</router-link>
      </nav>
    </header>
    
    <!-- 자식 라우트 컴포넌트가 여기에 렌더링됨 -->
    <router-view></router-view>
  </div>
</template>

3. 자식 컴포넌트 예시 (UserPosts.vue)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<template>
  <div class="user-posts">
    <h2>사용자 의 게시물</h2>
    <ul>
      <li v-for="post in posts" :key="post.id"></li>
    </ul>
  </div>
</template>

<script>
export default {
  data() {
    return {
      posts: []
    }
  },
  created() {
    // 사용자 ID를 기반으로 게시물 데이터를 가져오는 로직
    this.fetchPosts(this.$route.params.id)
  },
  methods: {
    fetchPosts(userId) {
      // API 호출 등
    }
  }
}
</script>

작동 방식

  1. 사용자가 /user/123 URL로 접속하면:

    • UserLayout 컴포넌트가 로드됩니다
    • 기본 자식 라우트인 UserProfile<router-view> 내부에 렌더링됩니다
  2. 사용자가 /user/123/posts URL로 이동하면:

    • UserLayout 컴포넌트는 그대로 유지됩니다
    • <router-view> 내부의 컨텐츠만 UserPosts 컴포넌트로 교체됩니다

더 깊은 중첩

중첩 라우트는 여러 수준으로 깊게 구성할 수도 있습니다:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
const routes = [
  {
    path: '/user/:id',
    component: UserLayout,
    children: [
      { path: '', component: UserProfile },
      { 
        path: 'posts', 
        component: UserPosts,
        children: [
          { path: ':postId', component: PostDetail } // /user/:id/posts/:postId
        ]
      }
    ]
  }
]

이러한 구조에서는 UserPosts 컴포넌트에도 <router-view>를 추가해야 PostDetail 컴포넌트가 렌더링됩니다.

Vue 3에서의 개선사항

Vue 3와 Vue Router 4에서는 Composition API를 사용한 중첩 라우트 처리가 가능합니다:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import { useRoute, useRouter } from 'vue-router'

export default {
  setup() {
    const route = useRoute()
    const router = useRouter()
    
    const userId = route.params.id
    
    // userId를 사용한 로직
    
    return { userId }
  }
}

중첩 라우트는 복잡한 UI 구조를 체계적으로 관리하고 일관된 사용자 경험을 제공하는 강력한 Vue Router 기능입니다.

–> 이런식으로 해서 일일 뷰를 띄우면 되겠다. 모달창으로 말이야

10.6 명명된 라우트와 명명된 뷰

10.6.1 명명된 라우트

1
2
3
4
<!-- router/index.js -->
const routes = [{ path: '/home', name: 'home', component: () => import('./Home.vue') }]
<!-- 사용 -->
<router-link :to="{ name: 'home' }">Home</router-link>

명명된 라우트는 경로 이름을 사용해 이동합니다.

10.6.2 명명된 뷰

1
2
3
4
5
6
7
8
9
10
<!-- App.vue -->
<template>
  <router-view name="header"></router-view>
  <router-view></router-view>
</template>
<!-- router/index.js -->
const routes = [{
  path: '/',
  components: { default: () => import('./Main.vue'), header: () => import('./Header.vue') }
}]

명명된 뷰는 여러 뷰를 한 페이지에 렌더링합니다.

10.7 프로그래밍 방식의 라우팅 제어

10.7.1 라우터 객체의 메서드

1
2
3
4
5
<script setup>
import { useRouter } from 'vue-router'
const router = useRouter()
const goHome = () => router.push('/')
</script>

router.push로 프로그래밍 방식으로 경로를 이동합니다.

10.7.2 내비게이션 가드

1
2
3
4
<!-- router/index.js -->
router.beforeEach((to, from) => {
  if (to.path === '/admin') return '/login'
})

내비게이션 가드는 라우팅 전후 동작을 제어합니다.

10.7.3 내비게이션 가드 적용하기

1
2
3
4
5
6
7
<script>
export default {
  beforeRouteEnter(to, from, next) {
    next()
  }
}
</script>

컴포넌트 내 가드로 특정 경로 접근을 관리합니다.

10.8 히스토리 모드와 404 라우트

10.8.1 히스토리 모드

1
2
3
<!-- router/index.js -->
import { createRouter, createWebHistory } from 'vue-router'
const router = createRouter({ history: createWebHistory() })

히스토리 모드는 깔끔한 URL을 제공합니다.

10.8.2 404 라우트

1
2
<!-- router/index.js -->
const routes = [{ path: '/:pathMatch(.*)*', component: () => import('./NotFound.vue') }]

404 라우트는 정의되지 않은 경로를 처리합니다.

10.9 라우트 정보를 속성으로 연결하기

1
2
3
4
5
6
7
8
9
<!-- User.vue -->
<template>
  <p>User: </p>
</template>
<script setup>
defineProps(['userId'])
</script>
<!-- router/index.js -->
const routes = [{ path: '/user/:userId', props: true, component: () => import('./User.vue') }]

라우트 파라미터를 속성으로 컴포넌트에 전달합니다.

10.10 지연 로딩

10.10.1 지연 로딩 적용하기

1
2
<!-- router/index.js -->
const routes = [{ path: '/', component: () => import('./Home.vue') }]

지연 로딩은 컴포넌트를 필요할 때만 로드합니다.

10.10.2 Suspense 컴포넌트

1
2
3
4
5
6
<template>
  <Suspense>
    <template #default><AsyncComp /></template>
    <template #fallback>Loading...</template>
  </Suspense>
</template>

Suspense는 비동기 컴포넌트 로딩 중 대체 UI를 표시합니다.

10.10.3 청크 스플릿팅

1
2
<!-- router/index.js -->
const routes = [{ path: '/', component: () => import(/* webpackChunkName: "home" */ './Home.vue') }]

청크 스플릿팅은 코드를 분할해 초기 로드 속도를 개선합니다.

10.11 라우팅과 인증 처리

10.11.1 토큰 기반 인증 개요

토큰 기반 인증은 사용자 인증을 위해 토큰을 활용합니다.

10.11.2 내비게이션 가드를 이용한 로그인 화면 전환

1
2
3
4
5
<!-- router/index.js -->
router.beforeEach((to, from, next) => {
  if (to.meta.requiresAuth && !localStorage.getItem('token')) next('/login')
  else next()
})

가드로 인증 여부를 확인해 로그인 화면으로 전환합니다.

10.12 마무리

vue-router를 활용하면 SPA에서 강력한 라우팅을 구현할 수 있습니다.

This post is licensed under CC BY 4.0 by the author.