Vue 3.0/05.vuerouter

[vue3-router] 01. 기본

  • -

이번 포스트에서는 Vue의 공식 라우터인 vue router에 대해서 살펴보자. 

SPA는 서버에 요청 시마다 웹 페이지를 새로 받아오지 않고 최초의 요청에서 전체를 받아온 후 보이는 컴포넌트만 교체하는 형식이다. 따라서 기본적으로 한 페이지이기 때문에 페이지 이동이라는 개념이 없다. 단지 컴포넌트의 교체만 존재할 뿐이다. router란 컴포넌트를 교체하면서 마치 페이지가 이동하는 것처럼 만들어주는 역할을 수행하는 라이브러리다.

 

vue router 기본

 

vue router 특징

vue router는 Vue에서 라우팅 기능을 지원하는 공식 라이브러리이다.

https://v3.router.vuejs.org/kr/

 

Vue Router

 

v3.router.vuejs.org

다음은 vue router의 주요 기능이다.

  • 중첩된 라우트 / 뷰 매핑
  • 모듈화 된 컴포넌트 기반의 라우터 설정
  • 라우터 파라미터, 쿼리, 와일드카드
  • vue.js의 트랜지션 시스템을 이용한 트랜지션 효과
  • 세밀한 내비게이션 컨트롤
  • active CSS 클래스를 자동으로 추가해 주는 링크
  • HTML5의 히스토리 모드 및 해시 모드 지원 등

 

vue router 설치

vue router를 설치하기 위해서는 프로젝트 생성 시 아래와 같이 선택해 주면 된다.

중간에 Add Vue Router for Single Page Application development? 에서 Yes를 선택하면 된다. 

프로젝트를 생성하고 나면 package.json의 dependencies 부분에 다음과 같이 vue-router가 추가된 것을 확인할 수 있다.

"dependencies": {
    "vue": "^3.3.4",
    "vue-router": "^4.2.4"
  }

vue router는 플러그인으로 사용하기 위해서는 몇 가지 설정이 필요한데 프로젝트 생성 과정에서 router를 추가 설정 한 경우 자동으로 진행된다. 

먼저 main.js에 보면 router를 import 하고 app.use(router) 함수를 통해 router 사용 설정이 되어있다.

import './assets/main.css'

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

const app = createApp(App)

app.use(router)

app.mount('#app')

 

또한 src/router/index.js 파일에 기본 라우터 코드가 생성돼서 편리하게 작업할 수 있다. 

import { createRouter, createWebHistory } from 'vue-router'
import HomeView from '../views/HomeView.vue'

const router = createRouter({
  history: createWebHistory(import.meta.env.BASE_URL),
  routes: [
    {
      path: '/',
      name: 'home',
      component: HomeView
    }
  ]
})

export default router

 

만약 vue router가 없이 생성된 프로젝트에 vue router를 추가하려면 아래와 같이 추가할 수 있다. 

npm install vue-router      // npm을 이용한 라이브러리 설치 방식

 

하지만 위와 같이 npm install로 라이브러리를 추가한 경우는 main.js에서 reouter를 등록하는 코드나 src/router/index.js 코드가 자동 삽입되지 않기 때문에 별도로 추가해주어야 한다.

기존의 vue cli에서는 vue 명령을 통해 router를 설치할 수 있었고 이 경우 템플릿을 만들어줬는데 vite에서는 그런 기능이 없는 것 같다.(vite는 vue 전용이 아니니까 당연한 것 같기는 하다.) 혹시 vite에서 vue plugin 설치 방법을 아시는 분 알려주세요!!

 

기본 구조

먼저 <template> 영역에서 vue router를 사용하기 위해서는 두 개의 간단한 태그가 사용된다. 이 태그는 기본 내장 컴포넌트를 사용하기 때문에 컴포넌트 형태로 사용해도 무방하다.

태그 설명
<router-link to="target_URL">
<RouterLink to="target_URL">
페이지 이동 태그로 화면에서 클릭 시 target_URL로 이동한다.
DOM에서는 <a>태그로 변환된다.
<router-view>
<RouterView>
변경되는 URL 따라 해당 컴포넌트를 표현하는 영역(outlet)

 

그리고 javascript에서는 VueRouter 객체가 사용된다. VueRouter는 vue-router 가 제공하는 createRouter 함수를 이용해서 생성된다.

router를 구성할 때는 vue-router가 제공하는 createRouter 함수에 옵션 객체를 전달하는데 상세한 내용은 차근차근 살펴보자.

import { createRouter, createWebHistory } from 'vue-router'
import HomeView from '../views/HomeView.vue'

const router = createRouter({
  // component와 route matching 작업
})

export default router

 

기본 라우팅 처리

 

자식 view 준비

먼저 이동 대상인 자식 view 들을 준비하자. 느닷없이 view가 나왔는데 사실은 이제까지 봤던 자식 component와 동일한 녀석이다. 특별히 view라고 구분하는 이유는 일반적으로 component는 부품으로 재사용되는 것들을 모두 이야기하는 것이고 component 중 router를 통해 이동하는 대상 즉 페이지의 개념으로 사용되는 component를 view로 분류한다.

/src/views/ 아래에 페이지로 사용할 EmptyView, SubPage1View, SubPage2View를 만들어보자.

<!-- src/views/EmptyView.vue -->
<template><div></div></template>

<!-- src/views/SubPage1View.vue-->
<template>
    <h2>여기는 sub page 1</h2>
</template>

<!-- src/views/SubPage2View.vue-->
<template>
    <h2>여기는 sub page 2</h2>
</template>

 

src/router/index.js

이제 router에서 컴포넌트와 경로를 매핑시켜 보자. 만들어진 기본 템플릿에 필요한 내용만 작성해 주면 되니 큰 어려움은 없을 것이다.

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

import EmptyView from '@/views/EmptyView.vue'
import SubPage1View from '@/views/SubPage1View.vue'
import SubPage2View from '@/views/SubPage2View.vue'

const router = createRouter({
  history: createWebHistory(import.meta.env.BASE_URL),
  routes: [
    {
      path: '/',
      component: EmptyView
    },
    {
      path: '/sub1',          // 필수: 요청 경로
      name: 'SubPage1View',   // 옵션: 경로 이름
      component: SubPage1View // 필수: 대상 컴포넌트
    },
    {
      path: '/sub2',
      name: 'SubPage2View',
      component: SubPage2View
    }
  ]
})

export default router

개별 경로(route)를 구성하는 속성 중 path와 component는 필수이고 name은 옵션이다. 비록 name 속성이 옵션이지만 다음의 장점이 있어서 사용권장 된다.

  • 일단 하드 코딩된 URL이 없다. 따라서 만약 URL이 변경되어야 하는 경우 그냥 router만 변경하면 끝이다. 만약 path 기반으로 작성된 앱이라면 모든 경로의 수정이 필요해진다.
  • path를 작성 시 URL에 오타를 방지할 수 있다.
  • params를 자동으로 인코딩/디코딩 해준다.

 

Vue Router에서 컴포넌트를 가져오는 방법은 정적 로딩과 동적 로딩이 있다.

import { createRouter, createWebHistory } from 'vue-router'
import HomeView from '../views/HomeView.vue'            // 정적 로딩

const router = createRouter({
  history: createWebHistory(import.meta.env.BASE_URL),
  routes: [
    {
      path: '/',
      name: 'home',
      component: HomeView
    },
    {
      path: '/about',
      name: 'about',
      component: () => import('../views/AboutView.vue') // 동적 로딩
    }
  ]
})

export default router

먼저 HomeView처럼 사용하는 것이 정적 로딩이고 AboutView에 있는 것처럼 import 함수 형태로 로딩하는 것을 동적 로딩이라고 한다. 이 둘의 차이점은 나중에 살펴보자.

https://goodteacher.tistory.com/678

 

[vue3-router] 07. 지연 로딩 경로

이번 포스트에서는 lazy loading route 즉 지연 로딩 경로라는 것에 대해서 알아보자. lazy loading route 우리는 SPA Vue의 큰 특징은 SPA 즉 Single Page Application이다. 이녀석은 "최초 사이트에 요청 시 전체 애

goodteacher.tistory.com

 

<template> 영역

<template>에서는 앞서 언급한 <RouterLink>와 <RouterView>를 이용해서 페이지 이동 링크와 하위 컴포넌트 표시 영역을 지정한다. <RouterLink>에는 to 속성을 이용해서 이동 대상 경로를 지정한다. 경로는 절대경로와 상태경로 모두 사용 가능하다.

<script setup></script>

<template>
  <header>
    <div class="wrapper">
      <h1>페이지 이동 테스트</h1>
      <nav>
        <RouterLink to="/">기본페이지</RouterLink>
        <RouterLink to="/sub1">절대경로: SubPage1View로 이동</RouterLink>
        <RouterLink to="./sub2">상대경로: SubPage2View로 이동</RouterLink>
      </nav>
    </div>
  </header>
  <!-- router의 url에 따라 갱신되는 영역 -->
  <RouterView />
</template>

<style scoped>
</style>

RouterLink나 RouterView는 모두 vue-router에 포함된 내장 컴포넌트이다. 따라서 router-link, router-view라고 사용하기도 한다.

 

개발자 도구 확인

개발자 도구를 통해서도 Vue-Router의 구성을 손쉽게 파악할 수 있다.

 

다양한 경로 활용

 

프로그래밍 방식 활용

위 예에서는 간단히 링크를 통한 페이지 이동에 대해 살펴봤는데 실제 개발을 하다 보면 프로그래밍적으로 페이지 이동을 처리해야 하는 경우가 많다. 이때는 vue-router가 제공하는 useRouter라는 함수를 통해 router 객체를 얻은 후 push 메서드를 이용해 이동할 경로를 전달해 주면 된다. 경로는 path 기반일 경우는 path, 이름 기반일 경우는 name 속성을 갖는 객체를 전달한다. 단 path의 경우는 그냥 path만 전달할 수도 있다.

 

대음은 moveTo라는 함수에 path가 전달될 때 그 경로로 이동하는 코드이다.

import { useRouter } from 'vue-router'
const router = useRouter()
const moveTo = (target) => {
  router.push({ path:target })         // path 기반일 경우: 객체 형태로 전달
  // router.push(target)               // path 기반일 경우: 경로만 전달 가능
  // router.push({ name:target })      // name 기반일 경우
  // router.replace({ name:target })   // name 기반일 경우: 경로 대체
}

push의 경우 이동 history에서 경로를 stack 개념으로 관리한다. 따라서 뒤로 가기 기능이 가능하다. A -> login -> (push)B에서 뒤로가기를 했다면 다시 login으로 이동한다. 이미 로그인 된 상태에서 대략 난감이다.

이런 경우는 replace 메서드를 사용한다. replace를 사용하면 현재 경로를 대체한다. 따라서 A -> login ->(replace)B로 이동했을 때 B에서 뒤로가기를 하면 A로 대체된다.  만약 RouterLink를 이용하려는 경우 뒤에 replace라고 추가해주면 된다.

<RouterLink to="/user" replace>User</RouterLink>

 

v-bind:to

to는 단순히 RouterLink에 선언된 속성이기 때문에 v-bind 속성을 이용해서 값을 매핑시키는 것도 물론 가능하다.

<!-- script 영역 -->
import { ref } from 'vue';
const sub2 = ref("SubPage2View");

<!-- template 영역 -->
<RouterLink :to="{ path: '/sub1' }">/sub1으로 이동</RouterLink> |
<RouterLink :to="{ name: sub2 }">/sub2으로 이동</RouterLink>

 

Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.