카테고리 없음

Vue route 설정으로 경로 변경

사람이슈 2022. 7. 7. 12:04

여러 페이지가 클라이언트 측(단일 페이지 응용 프로그램)에서 작동하도록 하려면 라우터가 필요합니다. 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을 존재하지 않는 것으로 변경하면 이제 버튼이 표시되고 클릭하면 질문 개요로 돌아갑니다.