[Vue] Router

배창민·2025년 11월 20일
post-thumbnail

Vue Router 정리

SPA에서 URL로 페이지를 다루는 방법


1. Vue Router 개념 잡기

1-1. Vue Router가 하는 일

Vue Router는 Vue 공식 라우팅 라이브러리다.

  • 하나의 HTML 안에서 URL만 바꾸면서 화면(컴포넌트)을 교체
  • 실제로는 페이지 전체 새로고침 없이 동작
  • 결국 URL → 컴포넌트 매핑 테이블을 만드는 것

SPA에서 단순히 v-if 로 화면을 바꿀 수도 있지만, 아래 기능을 제대로 쓰려면 라우터가 필수에 가깝다.

  • /users/1 같은 주소로 직접 접근
  • 뒤로가기 / 앞으로가기
  • 새로고침해도 같은 화면 유지

2. Vue Router 기본 설정 흐름

2-1. 설치

npm install vue-router@next

2-2. 기본 흐름

  1. routes 배열로 path → component 매핑 정의
  2. createRouter() 로 라우터 인스턴스 생성
  3. app.use(router) 로 Vue 앱에 플러그인 등록
  4. 템플릿에 <RouterView> 배치 (페이지가 들어갈 자리)

3. 라우트 테이블과 history 모드

3-1. 라우트 테이블 구조

const routes = [
  { path: '/', component: HomeView },
  { path: '/about', component: AboutView }
];
  • path : URL 패턴
  • component : 해당 URL에서 렌더링할 컴포넌트

3-2. createRouter + history 모드

import { createRouter, createWebHistory } from 'vue-router';

const router = createRouter({
  history: createWebHistory(), // 또는 createWebHashHistory()
  routes
});
  • createWebHistory()

    • HTML5 History API 사용
    • /about 처럼 깔끔한 URL
    • 서버에서 모든 요청을 index.html 로 돌려주는 설정 필요
  • createWebHashHistory()

    • /#/about 형태
    • 별도 서버 설정 거의 필요 없음
    • 토이 프로젝트, 내부 도구에 무난

실무에서는 보통 createWebHistory() 선택.

3-3. Vue 앱에 연결

import { createApp } from 'vue';
import App from './App.vue';
import router from './router';

createApp(App)
  .use(router)
  .mount('#app');

.use(router) 로 라우터를 전역 플러그인으로 등록한다.


4-1. <RouterView> – 페이지가 끼워지는 자리

<template>
  <div>
    <HeaderBar />
    <RouterView />
    <FooterBar />
  </div>
</template>
  • 현재 URL 에 대응하는 컴포넌트가 <RouterView> 위치에 렌더링
  • 헤더/푸터는 고정, 가운데 내용만 라우트에 따라 교체하는 패턴을 쉽게 만들 수 있다
<RouterLink to="/">Home</RouterLink>
<RouterLink to="/about">About</RouterLink>
  • <a href="..."> 와 비슷하지만 페이지 새로고침 없이 라우트 전환
  • 현재 라우트와 일치하면 자동으로 router-link-active 클래스 부여

replace 옵션

<RouterLink to="/login" replace>로그인</RouterLink>
  • 브라우저 히스토리에 새 기록을 남기지 않고 현재 기록을 대체
  • 로그인 후 뒤로가기 눌렀을 때 다시 로그인 페이지로 돌아오지 않게 만들 때 유용

5. useRoute / useRouter

5-1. useRoute – 현재 라우트 정보 읽기

import { useRoute } from 'vue-router';

const route = useRoute();

route.path;        // "/users/1"
route.params.id;   // "1"
route.query.page;  // "2" (예: ?page=2)
  • params, query, meta 등 라우트 관련 정보에 접근할 수 있다

5-2. useRouter – 코드에서 라우트 이동

import { useRouter } from 'vue-router';

const router = useRouter();

const goHome = () => {
  router.push('/');
};

const goUser = id => {
  router.push(`/users/${id}`);
};
  • router.push() : 히스토리에 기록 남기면서 이동
  • router.replace() : 현재 기록을 덮어쓰기

버튼 클릭, 폼 전송 이후 특정 페이지로 보내는 작업에 사용한다.


6. 동적 라우트 params / 쿼리 스트링

6-1. 동적 params – /users/:id

const routes = [
  { path: '/users/:id', component: UserDetailView }
];
  • /users/10 에 접근하면 route.params.id === "10"

  • 주로 리소스 식별자 표현에 사용

    • 예: /products/123, /posts/2024-11-20

6-2. 쿼리 스트링 – ?page=2&keyword=vue

// /search?keyword=vue&page=2
const route = useRoute();

route.query.keyword; // "vue"
route.query.page;    // "2"
  • 정렬, 검색, 필터 같은 옵션성 정보를 표현하기 좋다
  • 현재 검색 상태를 URL 로 공유하거나 북마크할 때 유용

간단히 정리하면

  • 리소스 “누구/무엇”을 가리킬 때 → params
  • “어떻게 볼 것인가” 옵션들 → query

7. 레이아웃 설계 – 헤더/푸터 유지

7-1. 기본 레이아웃 패턴

App.vue 같은 최상위 컴포넌트에서:

<template>
  <div>
    <HeaderBar />
    <main>
      <RouterView />  <!-- 페이지 영역 -->
    </main>
    <FooterBar />
  </div>
</template>
  • 모든 페이지에서 공통되는 레이아웃은 여기서 관리
  • 각 라우트 컴포넌트는 <RouterView> 안에만 집중

7-2. 중첩 라우트로 섹션 레이아웃 만들기

관리자 페이지 같은 경우:

const routes = [
  {
    path: '/admin',
    component: AdminLayout,     // 내부에 <RouterView> 포함
    children: [
      { path: 'users', component: AdminUsers },
      { path: 'settings', component: AdminSettings }
    ]
  }
];
  • /admin/users → AdminLayout + AdminUsers
  • /admin/settings → 같은 레이아웃 + AdminSettings

섹션별로 공통 레이아웃을 재사용할 수 있다.


8. 네비게이션 가드와 인증 흐름

8-1. 네비게이션 가드란

라우트가 변경되기 전에

  • 이 이동을 허용할지
  • 막을지
  • 다른 곳으로 리다이렉트할지

를 결정하는 훅이다.

종류

  • 전역 가드: router.beforeEach
  • 라우트별 가드: beforeEnter
  • 컴포넌트 내부 가드: beforeRouteLeave

기본적인 로그인/권한 체크는 보통 전역 beforeEach 에서 처리한다.

8-2. 전역 beforeEach 개념 흐름

  1. 사용자가 /mypage 로 이동 시도
  2. beforeEach 에서 로그인 여부, 권한 확인
  3. 필요 조건을 만족하지 않으면 /login 으로 이동
  4. 조건을 만족하면 라우트 이동 허용

Vue 3 에서는 next() 대신 return false, return { path: '/login' } 같은 패턴을 사용한다는 정도만 기억해 두면 된다.


9. meta로 인증 제어 패턴

9-1. meta 필드 사용

라우트 정의에 임의 정보를 붙일 수 있다.

const routes = [
  {
    path: '/mypage',
    component: MyPageView,
    meta: { requiresAuth: true }
  },
  {
    path: '/login',
    component: LoginView,
    meta: { guestOnly: true }
  }
];
  • requiresAuth : 로그인한 사용자만 접근 가능해야 하는 페이지
  • guestOnly : 로그인 안 한 사용자만 접근 가능 (로그인 페이지 등)

9-2. meta + beforeEach 조합

전역 가드에서:

  1. to.meta.requiresAuth 확인

    • true 인데 로그인 안 되어 있으면 /login 으로 리다이렉트
  2. to.meta.guestOnly 확인

    • true 인데 이미 로그인된 상태면 //mypage 로 돌려보내기

이 패턴을 쓰면

  • 라우트 정의에 “이 페이지는 인증 필요” 같은 정보를 붙이고
  • 실제 로직은 가드에서 한 곳에서 관리

라는 구조를 만들 수 있다.


10. Lazy-loading과 코드 스플리팅

10-1. Lazy-loading 이 필요한 이유

모든 페이지 컴포넌트를 한 번에 번들링하면

  • 초기 로딩 JS 파일이 커지고
  • 첫 화면이 뜨기까지 시간이 길어진다

사용자는 처음부터 모든 페이지에 가지 않는다.
그래서 필요한 페이지에 처음 들어갈 때만 해당 컴포넌트를 로딩하는 것이 효율적이다.

10-2. 동적 import로 Lazy-loading

const routes = [
  {
    path: '/about',
    component: () => import('../views/AboutView.vue')
  }
];
  • 함수 형태로 컴포넌트를 넘기면

    • 해당 라우트에 첫 방문할 때 네트워크 요청으로 컴포넌트를 가져온다
  • 번들러가 이 구문을 보고 코드 스플리팅 수행

효과

  • 초기 번들 크기 감소 → 첫 페이지 로딩 속도 개선
  • 사용자가 실제로 방문한 페이지에 대해서만 추가 로딩 발생

마무리 정리

  • Vue Router는 SPA에서 URL → 컴포넌트 매핑을 담당
  • <RouterView> 는 페이지가 들어가는 슬롯, <RouterLink> 는 SPA용 링크
  • useRoute 로 현재 라우트 상태를 읽고, useRouter 로 코드에서 이동 제어
  • 리소스 식별 → params (/users/:id), 옵션 값 → query (?page=2)
  • 레이아웃(헤더/푸터)은 상위 컴포넌트 + <RouterView> 조합으로 구성
  • 인증/권한은 meta + 전역 beforeEach 패턴으로 깔끔하게 관리
  • Lazy-loading 으로 페이지 단위 코드 스플리팅까지 하면 실전 구조와 거의 같아진다
profile
개발자 희망자

0개의 댓글