[Vue.js] Install Router, Routing, URL Parameter
✔️ Project setting
1. router 설치
npm install vue-router@4
2. router.js 설정
router.js
import { createWebHistory, createRouter } from "vue-router";
import List from "./components/List.vue";
const routes = [
{
path: "/list",
component: List.vue,
}
];
const router = createRouter({
history: createWebHistory(),
routes,
});
export default router;
상단 import 로 List Component 가져오고
path route 설정 한다음에 component 에 등록시키면 된다.
3. main.js 설정
main.js
import './assets/main.css'
import { createApp } from 'vue'
import App from './App.vue'
import 'bootstrap'
import 'bootstrap/dist/css/bootstrap.min.css'
import router from './router.js'
createApp(App).use(router).mount('#app')
main.js 에서 import 로 만든 router.js 파일 가져오고 use() 안에 작명 이름 넣어줘서 사용한다고 알리면 된다.
4. App.vue 에서 호출
<router-view :blog="blogs" ></router-view>
router-view 태그를 통해 원하는 route 로 접근 시 어디에 해당 Component 를 띄울 것인지를 지정한다.
반복문은 쓸 수 없으며 props 로 데이터를 전달할 때는 동일하게 위 코드처럼 전달할 수 있다.
5. router-link
<a class="nav-link" href="#"> <router-link to="/list">List</router-link>
router-link to ="/route" 를 통해 해당 route 로 이동할 수 있는 링크를 만들 수 있다.
6. styling
보통 router-view 나 router-link 태그에 직접 class 를 넣어 스타일링을 해주지 않고 그 위에를 div 로 묶어서 class 를 지정한다.
✔️ URL Parameter 를 이용한 상세페이지 기능
router.js
{
path: "/detail/:id(\\d+)",
component: Detail
}
detail 뒤에 :id 를 붙여서 URL Parameter 를 받도록 한다.
List.vue
<template>
<div>
<h3 class="mt-4">블로그 목록</h3>
<ul>
<li v-for="(blog, i) in blogs" :key="i">
<router-link :to="`/detail/${blog.number`">{{ blog.title }}</router-link>
</li>
</ul>
</div>
</template>
List Component 에서 title 리스트가 나오게 반복문을 사용했고, 안에 router-link 를 /detail/${i} 로 만들어서 해당 게시물로 상세페이지 링크가 이동되게끔 설정했다.
✔️ 불필요한 Component 에 props 제거
App.vue
<router-view :blogs="blogs" ></router-view>
기존 방식에서 Main,vue, List.vue, Detail.vue 이 세 Component 다 동일한 router-view 를 통해 호출되다 보니까 불필요하게 blogs 데이터가 전달되었다.
그래서 꼭 필요한 Component 에만 전달되도록 수정하고자 했다.
router.js
import blogs from "./assets/blog.js"
const routes = [
{
path: "/list",
component: List,
props: { blogs: blogs }
},
router.js 파일 상단에 data 파일을 import 해주고,
props 를 이 곳에서 걸어줬다.
{
path: "/detail/:id(\\d+)",
component: Detail,
props: (route) => {
const blogPost = blogs.find(blog => blog.number === parseInt(route.params.id));
return { blogPost };
}
}
또한 Detail 에다가 한 번에 props 를 추가해 데이터를 넣어주지 않고, Detail 에는 해당 id 값만 blogs 데이터에서 찾아서 객체로 게시물 하나만 전달하게 했다.
Detail.vue
<template>
<div>
<h3 class="mt-4">상세페이지</h3>
<h5>{{blogPost.title}}</h5>
<p>{{blogPost.date}}</p>
<div>{{blogPost.content}}</div>
</div>
</template>
<script>
export default {
name: 'Detail',
props: {
blogPost: Object
}
}
</script>
<style></style>
받아온 props 데이터를 선언해주고 위에서 사용해줬다.
✔️ props 방식과 import 방식의 차이
🚀 props 방식의 장점
✅ 재사용 가능 → Detail.vue는 어떤 데이터든 받을 수 있음 (blogData가 바뀌어도 문제 없음)
✅ 유지보수 쉬움 → 부모에서 데이터가 변경되면 자동 반영됨
✅ 유닛 테스트 가능 → 다른 데이터로 쉽게 테스트 가능
❌ import 방식의 단점
🚫 재사용 어려움 → Detail.vue는 blogData에 강하게 결합되어 있어 다른 프로젝트에서 사용하기 어려움
🚫 데이터 변경 어려움 → 부모(App.vue)에서 데이터를 바꿔도 Detail.vue는 그대로 (따로 수정해야 함)
🚫 유닛 테스트 어려움 → 데이터를 변경해서 테스트하기 어려움