[vue.js] Vue Router 정리

Yeonjoo Yoo·2022년 2월 9일
7

TIL

목록 보기
11/12
vue에서 페이지 이동을 위한 라이브러리인 vue router에 대해 정리하고자 한다.

Vue Router

뷰 라우터란?

  • vue.js에서 페이지 간 이동을 위한 라이브러리
  • vue.js 공식 라우터
  • 페이지 이동할 때 url 변경되면, 변경된 요소의 영역에 컴포넌트를 갱신
    • SPA의 특징
    • DOM을 새로 갱신하는 것 아님

주요 기능

  1. 중첩된 route/view mapping
  2. 모듈화된, 컴포넌트 기반의 라우터 설정
  3. 라우터 파라미터, 쿼리, 와일드카드
  4. Vue.js의 transition system을 이용한 트랜지션 효과
  5. 세밀한(Fine-grained) 네비게이션 컨트롤
  6. active CSS 클래스를 자동으로 추가해주는 링크
  7. HTML5 History 모드 또는 Hash 모드
    • auto-fallback in IE9
    • vue router에서 default는 Hash 모드
  8. 사용자 정의 가능한 스크롤 동작

설치 방법 (NPM)

npm install vue-router --save

예제

  • 폴더 구조
├── router
│   └── index.js
├── App.vue
└── main.js
  • router/index.js
import Vue from 'vue';
import VueRouter from 'vue-router';
import Info from '../views/Info.vue';

Vue.use(VueRouter);

export default new VueRouter({
	mode:'history', //해쉬값 제거 방식
    routes: [{
        path: '/', 
        redirect: '/home' 
    }, {
        path: '/home',
        component: () => import('../views/Main.vue'),
    }, {
        path: '/info',
        component: Info
    }]
});
  • App.vue
<template>
	<div id="app">
        <router-link to="/main">main</router-link>
        <router-link to="/info">info</router-link>
        <!-- convert -->
        <!-- <a href="#/main" class="">main</a> -->
		<router-view></router-view>	
	</div>
</template>
  • main.js
import Vue from 'vue';
import App from './App.vue';
import router from './router/index.js';

new Vue({
  router,
  render: h => h(App),
}).$mount('#app')

설명

기초

  • <router-link to="경로"> 태그

    • 컴파일 시, <a> 태그로 변환
    • to 속성
      • to 속성 값의 경로로 이동
      • v-bind와 함께 사용하면 동적으로 경로를 만들 수 있음
      • to="test/path" 처럼 붙이면 현재 url에 이 path가 붙고,
        to="/test/detail" 처럼 붙이면 default url에 붙음 (대표적)
    • styling : router-link-exact-active 등 class를 통해 스타일을 줄 수 있음
  • <router-view>

    • 페이지 표시 태그
    • url에 따른 컴포넌트가 화면에 그려지는 영역

Dynamic Routing

  • url-path를 동적으로 요청받아 데이터를 넘길 수 있는 라우팅 방식 (파라미터 전달)
    반대로 해당 파라미터 정보를 가져올 때는 $route 객체를 참조하면 됨
  • 동적 세그먼트는 앞에 :가 붙음
    예) path='/user/:username/post/:post_id'
    만약, path='/user/emma/post/77' 라면, 라우팅된 컴포넌트에서
    this.route.params.username==emmathis.route.params.username == 'emma' this.route.params.post_id == 77
  • 동일한 컴포넌트를 재사용
    즉, 컴포넌트의 lifecycle hook이 호출되지 않기 때문에 params 변경사항에 반응하기 위해서는 watch 옵션으로 $route객체의 수정을 감지해야함
// router.js
// 만약, url이 '/post/123'라면 :[id]=123 데이터와 함께 PostItem 컴포넌트로 이동
const router = new VueRouter({
	routes: [{
		path : '/post/:id'
        component : () => import('../views/PostItem.vue')
	}]
});

// PostItem.vue
// this.$route.params.id로 값을 전달 받을 수 있음
created() {
  getPost('requestPost', this.$route.params.id);
}

Nested Routers

  • 라우터 컴포넌트 안에 하위 라우터 컴포넌트를 중첩하여 구성하는 방식
  • 라우터로 화면을 이동할 때 하위 컴포넌트를 표시할 수 있음
  • 라우터 설정에서 children 옵션 사용 (Parent - Child 형태)
<div id="app">
  // url="/user/.."인 경우 User 컴포넌트가 들어옴 
  <router-view></router-view>
</div>
const User = {
  template: `
    <div class="user">
	  <h2>User {{ $route.params.id }}</h2>
	  // id값에 맞는 User의 하위 컴포넌트가 들어옴 
      <router-view></router-view>
    </div>
  `,
}

const routes = [
  {
    path: '/user/:id',
    component: User,
    children: [
      {
        // /user/:id/profile is matched
        path: 'profile',
        component: UserProfile,
      },
      {
        // /user/:id/posts is matched
        path: 'posts',
        component: UserPosts,
      },
    ],
  },
]

Named Views

  • 특정 url 주소에 여러 컴포넌트들을 영역별로 지정하여 렌더링하는 것
  • 여러 개의 컴포넌트를 동시에 표시하게하는 방식 (같은 레벨)
  • 라우터 설정에서 components 옵션 사용
// App.vue
<div id="app">
  <router-view name="appHeader"></router-view>
  <router-view></router-view>
  <router-view name="appFooter"></router-view>
</div>

// router.js
{
  path: '/home',
  // Named Router
  components: {
    appHeader: AppHeader,
    default: Body,
    appFooter: AppFooter
  }
},

Nested Router vs Named Views

  • Nested Router: 특정 URL에 지정된 1개의 컴포넌트가 여러 개의 하위 컴포넌트를 갖는 것
  • Named View: 특정 URL에 여러 개의 컴포넌트를 영역 별로 지정하여 렌더링 하는 것

Named Routes

  • router-link에 to 속성에 path 대신 name을 지정 가능
<router-link :to="{ name: 'user', params: { username: 'erina' }}">
  User
</router-link>
const routes = [
  {
    path: '/user/:username',
    name: 'user',
    component: User
  }
]

Mode 속성

  • Vue Router의 기본모드는 Hash Mode
  1. Hash Mode
    • 브라우저에서 화면 위치를 변경할 때 url에 '#' + '위치'를 붙이면, 서버에 요청을 보내지 않고 이동 가능
      즉, Vue에서 페이지 전환 시 url이 변경되어도 페이지가 리로드되지 않음(요청 없이 Vue Router를 통해 브라우저에서 처리)
    • url에 '#'이 붙는 다는 단점이 있음
  2. History Mode
    • '#' 안 들어가고 SPA구현하게 하기 위한 모드 (url이 정상적으로 보임)
    • html 5가 제공하는 'history API'를 이용
  • <router-link>를 쓰면 모드에 맞는 url을 적용해줌

Router Transition

  • Vue Router 에서 API로 기본적으로 제공하는 트랜지션
  • 다른 페이지(라우트)로 전환될 때 페이지에 애니메이션이 들어감
  • <transition> 태그에 name 속성 값을 기반으로 클래스가 적용됨
    • 트랜지션 클래스(.[name]-enter, .[name]-enter-active, [name]-leave-to 등) 를 설정해주면 됨
<template>
  <transition name="fade">
    <router-view class="main"></router-view>
  </transition>
</template>
<style scoped>
/* CSS : Router Transition */
.fade-enter-active, .fade-leave-active {
  transition: opacity .5s;
}

.fade-enter, .fade-leave-to {
  opacity: 0;
}
</style>
  • <router-link :to="..."> 와 router.push(...)는 같음

redirect 옵션

  • 예시
// '/a'에서 '/b'로 리디렉션
routes: [{path : '/a', redirect: '/b'}]
// 이름이 있는 라우터의 경우
routes: [{path : '/a', redirect: {name: 'babo'}}]
// 함수를 사용하여 동적 리디렉션 가능 
routes: [{path : '/a', redirect: to => {return '/with-params:id'}}]

Alias (별칭)

  • url을 다르게 표시 가능
  • 예시 : '/b'를 방문시에도 url을 '/a'에 방문한 것처럼 표시
routes: [
{ path: '/a', component: A, alias: '/b' }]

props 옵션 (라우트 컴포넌트에 속성 전달)

  • props: true로 설정하면 $route.params가 컴포넌트 props로 사용 가능
  • 컴포넌트에서 $route를 사용하게 되면, 컴포넌트가 URL에 의족적이게 되어 재사용성이 떨어짐
    이 의존성을 제거하기 위해서 props 옵션을 사용
// $route에 의존성이 걸려있는경우
template: '<div>User {{ $route.params.id }}</div>'

// 의존성 해제
// 1. Boolean mode (props: true / false)
const User = {
 props: ['id'],
 template: '<div>User {{ id }}</div>'
}
{ path: '/user/:id', component: User, props: true }

// 2. Object mode
{ path: '/promotion/from-newsletter', component: Promotion, props: { newsletterPopup: false } }

// 3. Function mode
// props를 반환하는 함수도 만들 수 있습니다.
{ path: '/search', component: SearchUser, props: (route) => ({ query: route.query.q }) }

// named view + Boolean mode
{ path: '/user/:id', components: { default: User, sidebar: Sidebar }, props: { default: true, sidebar: false } }
  • props를 함수로 만들 때 유의 사항 중 한가지는 route가 변경되었을 때 호출 되는 함수이기 때문에 이 함수에서 state를 저장하면 안 됨

참고
https://router.vuejs.org
https://2dongdong.tistory.com/41
https://soheemon.tistory.com/entry/2021-03-15-vue-Router

profile
to be frontend engineer

1개의 댓글

comment-user-thumbnail
2023년 10월 17일

감사합니다 작은 기본 지식 얻고갑니다.

답글 달기