본문 바로가기

카테고리 없음

Vue route 설정으로 경로 변경

여러 페이지가 클라이언트 측(단일 페이지 응용 프로그램)에서 작동하도록 하려면 라우터가 필요합니다. Vue의 좋은 점은 라우팅과 같은 많은 모듈이 공식적으로 출시되어 타사 라이브러리가 필요하지 않다는 것입니다. 우리의 경우 vue-router를 사용하여 이 작업을 수행할 수 있습니다.

 

시으작

첫 번째 단계는 vue-router 종속성을 설치하는 것입니다.

npm install --save vue-router

그런 다음 src/router/index.js라는 파일을 만들고 다음 코드를 작성하여 라우터 모듈을 사용하도록 Vue에 지시할 수 있습니다.

import Vue from 'vue';
import Router from 'vue-router';

Vue.use(Router);

라우팅 정의

프로젝트를 설정한 후 동일한 파일 내에서 경로 정의를 시작할 수 있습니다.

export default new Router({
  routes: [{
    path: '/questions',
    name: 'Questions',
    component: QuestionsPage
  }]
});

이 코드 조각은 이전 자습서의 QuestionsPage 구성 요소를 /questions 경로에 매핑합니다. 페이지 구성 요소가 표시될 콘센트가 여전히 필요합니다. 지난 시간에는 앱 구성 요소 내에 QuestionsPage 구성 요소를 직접 포함했습니다. 이것이 작동하는 동안 이제 라우터가 표시하도록 지시하는 것으로 교체하려고 합니다.

 

이렇게 하려면 <QuestionsPage> 줄을 <router-view/>로 교체해야 합니다.

<template>
  <div id="app">
    <div class="container">
      <SiteHeader></SiteHeader>
      <div class="inner-container">
        <router-view/>
      </div>
    </div>
  </div>
</template>

QuestionsPage 구성 요소의 가져오기를 제거할 수도 있습니다.

 

이제 이 라우터 구성을 애플리케이션으로 가져오기만 하면 됩니다. 그렇게 하려면 src/main.js를 열고 Vue 인스턴스에 다음을 추가합니다.

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

import도 잊지 마세요.

import router from './router';

push-state 사용

지금 응용 프로그램을 열면 빈 페이지가 표시됩니다. 그러나 http://localhost:8080/#/questions로 이동하면 질문 경로가 제대로 제공되고 질문이 다시 표시되는 것을 볼 수 있습니다.

 

하지만 이것에 대해 마음에 들지 않는 점은 우리가 경로 내에서 해시태그를 사용한다는 것입니다. 다행히도 푸시 상태 또는 기록 기반 라우팅을 사용하여 이 문제를 제거할 수 있습니다. 이것을 변경하려면 src/router/index.js를 다시 열고 라우터 생성자에 mode 속성을 추가해야 합니다.

export default new Router({
  routes: [{
    path: '/questions',
    name: 'Questions',
    component: QuestionsPage
  }],
  mode: 'history' // Add this
});

http://localhost:8080/questions로 이동하여 경로가 다시 작동하는지 확인할 수 있습니다.

 

Redirecting

아직 마음에 들지 않는 또 다른 점은 http://localhost:8080/questions로 직접 이동해야 한다는 것입니다. 루트 URL이 자동으로 /questions로 리디렉션된다면 좋지 않을까요? 분명히 경로 경로를 /로 변경할 수 있으며 작동하지만 /questions를 유지하고 해당 경로로 리디렉션하고 싶습니다.

 

이렇게 하려면 새 경로를 추가하고 리디렉션 속성을 사용할 수 있습니다.

export default new Router({
  routes: [{
    path: '/questions',
    name: 'Questions',
    component: QuestionsPage
  }, {
    path: '/',
    name: 'Home',
    redirect: {name: 'Questions'}
  }],
  mode: 'history'
});

리디렉션 속성 내에서 경로를 정의하거나(redirect: '/questions) 위에서 볼 수 있듯이 name 속성이 있는 객체를 전달하여 경로 이름으로 리디렉션할 수 있습니다.

 

http://localhost:8080으로 이동하여 애플리케이션을 방문하면 /questions로 제대로 연결되어 작동하는 것을 볼 수 있습니다.

wildcard routes 사용

추가하고 싶은 또 다른 기능은 잘못된 경로를 열 때 오류 페이지가 표시된다는 것입니다. Vue에서는 와일드카드 경로를 추가하여 이를 수행할 수 있습니다.

export default new Router({
  routes: [{
    path: '/questions',
    name: 'Questions',
    component: QuestionsPage
  }, {
    path: '/',
    name: 'Home',
    redirect: {name: 'Questions'}
  }, {
    path: '*',
    name: 'NotFound',
    component: NotFoundPage
  }],
  mode: 'history'
});

와일드카드 *는 모든 경로와 일치하므로 Vue는 배열이 정의된 것과 동일한 순서로 일치하는 경로를 확인하므로 경로 맨 아래에 배치해야 합니다. 즉, 와일드카드 경로를 맨 위에 놓으면 질문 또는 홈 경로를 열려고 하는 경우에도 항상 일치합니다.

 

이제 경로를 정의했으므로 src/core/NotFoundPage.vue라는 새 Vue 구성 요소를 만들고 일부 마크업을 추가할 수 있습니다. 예를 들면 다음과 같습니다.

<template>
  <div>
    <h1 class="page-title center">
      <i class="icon icon-activity"></i><br />
      Looks like you made a wrong turn,<br />
      the page you requested isn't available.
    </h1>
  </div>
</template>

이제 경로가 있으므로 해당 링크를 클릭하고 적절한 경로로 이동할 수 있도록 SiteHeader 구성 요소를 수정해야 합니다. 실제로 그렇게 하기 전에 src/compponents/users/UsersPage.vue라는 사용자 페이지용 더미 구성 요소를 정의하겠습니다.

 

그런 다음 /users라는 경로를 추가하겠습니다.

export default new Router({
  routes: [{
    path: '/questions',
    name: 'Questions',
    component: QuestionsPage
  }, {
    path: '/users',
    name: 'Users',
    component: UsersPage
  }, {
    path: '/',
    name: 'Home',
    redirect: {name: 'Questions'}
  }, {
    path: '*',
    name: 'NotFound',
    component: NotFoundPage
  }],
  mode: 'history'
});

이제 경로가 있으므로 <router-link>를 사용하여 경로 링크를 추가할 수 있습니다.

<template>
  <at-menu mode="horizontal" active-name="questions">
    <at-menu-item name="questions">
      <router-link :to="{name:'Questions'}">
        <i class="icon icon-home"></i> Questions
      </router-link>
    </at-menu-item>
    <at-menu-item name="users">
      <router-link :to="{name: 'Users'}">
        <i class="icon icon-users"></i> Users
      </router-link>
    </at-menu-item>
  </at-menu>
</template>

앵커 태그를 사용하고 href 속성을 사용하여 특정 경로로 이동할 수도 있습니다. 그러나 이렇게 하면 페이지가 완전히 다시 로드되므로 응용 프로그램도 다시 로드됩니다. 이것은 페이지 구성 요소를 변경하는 것보다 훨씬 느릴 수 있습니다.

 

활성 경로에 따라 CSS 클래스를 변경하려면 활성 클래스 속성을 사용할 수 있습니다. 그러나 AT UI는 메뉴 구성 요소에서 경로를 지원하므로 대신 사용하겠습니다. 따라서 <router-link> 요소를 제거하고 <at-menu-item>에 :to 속성을 넣습니다. 마지막으로 <at-menu> 요소에 라우터 속성을 추가해야 합니다.

<template>
  <at-menu mode="horizontal" router>
    <at-menu-item name="questions" :to="{name: 'Questions'}">
      <i class="icon icon-home"></i> Questions
    </at-menu-item>
    <at-menu-item name="users" :to="{name: 'Users'}">
      <i class="icon icon-users"></i> Users
    </at-menu-item>
  </at-menu>
</template>

지금 애플리케이션을 살펴보면 페이지를 새로고침한 후에도 활성 메뉴 항목이 항상 올바른 것을 알 수 있습니다.

 

프로그래밍 방식으로 경로 변경

찾을 수 없는 페이지를 기억하십니까? 모든 질문의 개요로 쉽게 돌아갈 수 있도록 버튼을 추가하고 싶습니다. 우선, 라우터 상태를 변경할 메서드를 구성 요소에 정의해야 합니다. this.$router.push()를 사용하여 수행할 수 있습니다.

export default {
  methods: {
    openQuestions () {
      this.$router.push({name: 'Questions'});
    }
  }
}

다음 단계는 템플릿에 버튼을 추가하는 것입니다.

<at-button size="large" type="primary" hollow="true" icon="icon-home" v-on:click="openQuestions">
  Go back to the question overview
</at-button>

URL을 존재하지 않는 것으로 변경하면 이제 버튼이 표시되고 클릭하면 질문 개요로 돌아갑니다.