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