동적 라우트 매칭(Dynamic Route Matching)
주어진 패턴을 가진 라우터를 동일한 컴포넌트에 매핑할 때 동적 세그먼트를 사용하는 것
const User = {
template: '<div>User</div>'
}
const router = new VueRouter({
routes: [
// 동적 세그먼트는 콜론으로 시작
{ path: '/user/:id', component: User }
]
})
이 경우 /user/kim
과 /user/park
은 같은 경로에 매핑된다.
동적 세그먼트는 콜론:
으로 표시하고 라우트가 일치하면 동적 세그먼트의 값은 모든 컴포넌트에서this.$route.params
로 표시된다.
const User = {
template: '<div>User {{ $route.params.id }}</div>'
}
동일한 라우트에 여러 동적 세그먼트를 가질 수 있으며 $route.params
의 해당 필드에 매핑된다.
/user/kim/gender/male => { username:'kim', gender:'male' }
UserView 구현
1. src/routers/index.js
에 UserView.vue
라우터 연결
import Vue from "vue";
import VueRouter from "vue-router";
import UserView from "../views/UserView.vue";
Vue.use(VueRouter);
export const router = new VueRouter({
mode: "history",
routes: [
{
// 파라미터 변수 연결 시 : 이용
path: "/user/:id",
component: UserView,
},
],
});
2. src/store/index.js
에 state
속성 값 추가
export const store = new Vuex.Store({
state: {
user: {},
},
});
3. src/api/index.js
에 User정보 받아오는 API 설정
import axios from 'axios';
const config = {
baseUrl: "https://api.hnpwa.com/v0/",
};
function fetchUserInfo(username) {
return axios.get(`${config.baseUrl}user/${username}.json`);
}
export { fetchUserInfo };
4. src/store/actions.js
에 API에서 받아온 정보 처리 설정
import { fetchUserInfo } from "../api/index.js";
export default {
FETCH_USER({ commit }, name) {
fetchUserInfo(name)
.then(({ data }) => {
commit('SET_USER', data);
})
.catch((error) => {
console.log(error);
})
}
};
5. src/store/mutations.js
에 User정보 세팅하는 함수 설정
export default {
SET_USER(state, user) {
state.user = user;
}
};
6. UserView.vue
수정
<template>
<div>
<!-- 데이터 뿌려주기 -->
<p>name : {{ userInfo.id }}</p>
<p>karma : {{ userInfo.karma }}</p>
<p>created : {{ userInfo.created }}</p>
</div>
</template>
<script>
export default {
// 연산식 이용하여 store 변수 간편화
computed: {
userInfo() {
return this.$store.state.user;
},
},
// API 호출
created() {
const userName = this.$route.params.id;
this.$store.dispatch("FETCH_USER", userName);
},
};
</script>
<style>
</style>
결과
ItemView 구현
1. src/routers/index.js
에 ItemView.vue
라우터 연결
import Vue from "vue";
import VueRouter from "vue-router";
import ItemView from "../views/ItemView.vue";
Vue.use(VueRouter);
export const router = new VueRouter({
mode: "history",
routes: [
{
// 파라미터 변수 연결 시 : 이용
path: "/item/:id",
component: ItemView,
},
],
});
2. src/store/index.js
에 state
속성 값 추가
export const store = new Vuex.Store({
state: {
item: {},
},
});
3. src/api/index.js
에 Item정보 받아오는 API 설정
import axios from 'axios';
const config = {
baseUrl: "https://api.hnpwa.com/v0/",
};
function fetchCommentItem(id) {
return axios.get(`${config.baseUrl}item/${id}.json`);
}
export { fetchCommentItem };
4. src/store/actions.js
에 API에서 받아온 정보 처리 설정
import { fetchCommentItem } from "../api/index.js";
export default {
FETCH_ITEM({ commit }, id) {
fetchCommentItem(id)
.then(({ data }) => {
commit('SET_ITEM', data);
})
.catch((error) => {
console.log(error);
})
}
};
5. src/store/mutations.js
에 Item정보 세팅하는 함수 설정
export default {
SET_ITEM(state, item) {
state.item = item;
}
};
6. ItemView.vue
수정
<template>
<div>
<!-- 질문 상세 정보 -->
<section>
<div class="user-container">
<div>
// Font Awesome User Icon
<i class="fas fa-user"></i>
</div>
<div class="user-description">
// User 상세 연결
<router-link :to="`/user/${fetchedItem.user}`">{{ fetchedItem.user }}</router-link>
<div class="time">{{ fetchedItem.time_ago }}</div>
</div>
</div>
<h2>{{ fetchedItem.title }}</h2>
</section>
<!-- 질문 내용 -->
<section>
<div v-html="fetchedItem.content"></div>
</section>
</div>
</template>
<script>
import { mapGetters } from "vuex";
export default {
computed: {
...mapGetters(["fetchedItem"]),
},
created() {
const itemId = this.$route.params.id;
this.$store.dispatch("FETCH_ITEM", itemId);
},
};
</script>
<style scoped>
.user-container {
display: flex;
align-items: center;
padding: 0.5rem;
}
.fa-user {
font-size: 2.5rem;
}
.user-description {
padding-left: 8px;
}
.time {
font-size: 0.7rem;
}
</style>
※ Font Awesome 사용하기 위해선 public/index.html
에 Font Awesome CDN 추가 필요
결과
라우터 트랜지션(Router Transition)
라우터에서도 트랜지션을 사용 가능. 트랜지션에 대한 정보는 이전 [Vue.js] Todo App 사용자 경험 개선하기 포스팅 참조
구현
<transition>
<router-view></router-view>
</transition>
'Dev > Vue.js' 카테고리의 다른 글
[Vue.js] HackerNews - Mixin과 하이 오더 컴포넌트 (0) | 2020.09.24 |
---|---|
[Vue.js] Hacker News - 컴포넌트 공통화 (0) | 2020.09.23 |
[Vue.js] Hacker News - 스토어 구현 (0) | 2020.09.18 |
[Vue.js] Hacker News - API 구현 (0) | 2020.09.17 |
[Vue.js] Hacker News - 라우터 기본 (0) | 2020.09.17 |
댓글