즐코

[vue] 라우팅 본문

Vue

[vue] 라우팅

YJLEE_KR 2022. 11. 14. 18:05

vue-router

뷰에서 라우팅 기능을 구현할 수 있도록 지원하는 공식 라이브러리인 vue-router를 사용하여 라우팅을 해본다.

npm i vue-router

router-link 와 router-view

- router-link : a 태그와 같은 역할을 한다. to에 이동할 URL을 넣는다.

a 태그와의 다른점은 reload없이 url을 이동시켜준다! 화면 깜박임이 없다.

 

- rotuer-view : 특정 url로 이동 시 vueRouter 인스턴스 상에 정의한 component 를 렌더해줄 위치를 나타낸다. 

// 페이지 이동 태그
// 기본적으로 화면에서는 <a> 태그로 표시된다.
<router-link to='이동할 URL'></router-link>

// 페이지 표시 태그
// 변경되는 url에 따라 각 url에 해당하는 컴포넌트가 렌더되는 영역
<router-view></router-view>

vue router 인스턴스 생성하기

Vue.use()를 통해 플러그인을 설치해서 사용한다. 모든 컴포넌트에서 this.$router를 통해 VueRouter 인스턴스 활용이 가능하다.

 

routes 속성 : 각 path와 그에 해당하는 component 리스트들이다. 

       - path : 이동할 url 정의

       - component : 해당 path에 따라 렌더할 컴포넌트 정의 

// src/routes/index.js

import Vue from 'vue';
import VueRouter from 'vue-router';
import LoginPage from '@/views/LoginPage.vue';

Vue.use(VueRouter); // 뷰라우터 플러그인 설치

// 뷰라우터 인스턴스 생성
export default new VueRouter({
    routes : [
      { path: '/login', component: LoginPage },
    ],
})

vue 프로젝트의 진입점인 main.js 의 Vue 인스턴스에 해당 속성을 넣어주면 끝

// src/main.js
import Vue from 'vue';
import App from './App.vue';
import router from '@/routes/index';
import store from '@/store/index';

Vue.config.productionTip = false;

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

 

코드 스플리팅?

로드 시 모든 페이지를 다 가져오는 게 아니라, 각 url에 해당하는 페이지만 가져오게하는 게 코드 스플리팅의 역할

component에 가져온 컴포넌트를 넣는게 아니라, import문을 return하는 함수를 넣어준다.

// src/routes/index.js 일부
// 각 url로 이동할 때마다 필요한 자바스크립트 코드를 그때그때 가져오는 게 코드스플리팅이다!
export default new VueRouter({
  routes: [
    {
      path: '/login',
      //   component: LoginPage,
      component: () => import('@/views/LoginPage.vue'),
    },
    {
      path: '/signup',
      //   component: SignupPage,
      component: () => import('@/views/SignupPage.vue'),
    },
  ],
});

코드 스플리팅 전과 후 ⇒ 초기 애플리케이션 로딩 속도를 개선할 수 있다

 

코드 스플리팅 전과 후

redirect

특정 url로 들어갔을 시 다른 링크로 바로 통하게끔 설정해주는 것

  • 메인('/') 으로 들어갔을 시 바로 login 링크로 들어가게끔 설정해준 예시
export default new VueRouter({
  routes: [
    {
      path: '/',
      redirect: '/login',
    },
  ],
});

 

없는 페이지 접근 시 라우터 처리 

- 와일드카드(*)를 path로 지정해준다. 정의하지 않은 path에 대해선 NotFound 페이지를 만들어주면 좋다.

export default new VueRouter({
  routes: [
    {
      path: '*', // 위에서 정의된 다른 path들을 제외한 모든 path들 
      component: () => import('@/views/NotFoundPage.vue'),
    },
  ],
});

router mode 설정

대표적으로 mode 속성에는 hash와 history가 있다.

 

1. mode : hash

- router mode의 default 값은 hash 이다.

localhost:3000/#/login 이런식으로 url이 잡히는데, 이렇게 해시 값이 들어가버리면 # 때문에 서버가 읽지 못하고 페이지 유무를 파악하기 어려워서 검색엔진으로 읽지 못한다.

 

2. mode : history

hash와 달리 #값을 없애기 위해 mode 속성엔 history도 있다. html5가 제공하는 History API를 사용하였다.

이럴 경우 배포 시에 서버에 추가적인 세팅이 필요하다고 한다.

(루트 도메인이 아닌 다른 path에서 새로고침 할 경우 404 에러가 발생한다)

export default new VueRouter({
	mode: 'history'
})

 

this.$router와 new VueRouter() 를 콘솔창에 찍어보았다.

라우팅 해둔 페이지들을 나타낸 routes와 history로 설정한 mode가 VueRouter에 추가되었음을 확인할 수 있다.

 

 

this.$router.push(이동할 url)

자바스크립트를 사용해서 페이지 이동할땐 this.$router.push() 를 사용해주면 된다!

아래와 같이 디테일하게 속성을 설정할 경우도 있을 것 같아 기록해둔다.

this.$router.push({ path: '/main', query: { idx: useridx }})
// idx = 1 이면 /main/idx=1 이런식으로 url이동
this.$router.push({ path: '/main', hash: useridx })
// idx = 1 이면 /main#1 이런식으로 url이동

 

동적 라우팅

늘 그렇듯 라우트 매개변수를 활용해준다.

// src/routes/index.js
   {
      path: '/posts/:id',
      component: () => import('@/views/DetailPage.vue'),
    },

this.$route.params.매개변수명 으로 이를 컴포넌트 내에서 가져다 활용할 수 있다.

만약 이 id를 활용해서 백서버로 요청을 보내거나 컴포넌트를 구성해야한다면, 뷰 컴포넌트의 라이프사이클 중 created에 해주는게 좋다. created는 화면에 렌더되기 전 즉, 컴포넌트가 생성된 직후의 동작을 구현하는 영역이기 때문이다.

다만, 궁금해서 mounted (컴포넌트 화면 렌더 직후)에도 해봤는데, 되긴 되더라,, 하지만 아래처럼 콘솔을 찍어보니 created가 당연히 먼저 찍혔고, 느린 3G 환경에서 해보니 created에 하는 게 맞는 것 같다. 

// src/views/DetailPage.vue

<template>
  <div>
    <PostDetail :id="id"></PostDetail>
  </div>
</template>

<script>
import PostDetail from '@/components/posts/PostDetail.vue';
import { getDetailPost } from '../api';
export default {
  components: {
    PostDetail,
  },
  data() {
    return {
      id: '',
    };
  },
  created() {
    this.id = this.$route.params.id;
    getDetailPost(this.id).then(res => {
      console.log(res, '화면 렌더되기 전/컴포넌트가 생성된 직후');
    });
  },
  mounted() {
    this.id = this.$route.params.id;
    getDetailPost(this.id).then(res2 => {
      console.log(res2, '화면 렌더된 직후');
    });
  },
};
</script>

 

Nested routers vs Named Views

Nested Routers

- 특정 라우터 컴포넌트 안에 하위 라우터 컴포넌트를 중첩하는 방식

- 기본적인 path / component 속성 외에 children이라는 속성을 추가하여 배열상에 또 path 와 component를 정의한다

<div id="app">
  <router-view></router-view> // url이 /post/..일 경우 post 컴포넌트가 이 자리에 들어옴 
</div>
// src/views/PostPage.vue

<template>
  <div>
    <h2>{{ $route.params.id }}</h2>
    <router-view></router-view> // PostPage의 하위 컴포넌트가 들어오는 영역
  </div>
</template>
// src/routes/index.js

{
    path: '/post/:id',
    component: PostPage,
    children: [
    	{ 
            path: 'reply', // /post/:id/reply 일때 아래 컴포넌트가 렌더됨
            component: Reply,
        }, 
        {
            path: 'details', // /post/:id/details 일때 아래 컴포넌트가 렌더됨
            component: Detail,
        }
    ]
}

 

Named Views

- 특정 url에 여러 컴포넌트들을 영역별로 지정하여 렌더링하는 방식

- 기본적인 component 속성 정의 시 각 컴포넌트에 이름을 붙여서 정의해준다.

- name 속성을 사용해서 원하는 위치에 배치시킨다.

<div id="app">
    <router-view name="appHeader"></router-view>
    <router-view></router-view>
    <router-view name="appFooter"></router-view>
</div>
// src/routes/index.js

{
    path: '/main',
    components: {
    	appHeader: AppHeader,
        default: Body,
        appFooter: AppFooter
    }
}

 

기본적인건 이정도인 것 같다. 추가적으로 발견하는 것들은 다른 포스팅으로 정리할 예정이다.

Comments