Today I Learned ... Vue.js
🙋♂️ Reference Book
DAY 03 - 220530
- mock 서버
- 서버 데이터 바인딩
- 컴포넌트 심화
API 개발을 위한 협업 플랫폼.
API 테스트, 모니터리으 공유 등의 기능을 함.
-> 제대로 동작하는지 테스트 용도로 주로 사용됨.
테스트 기능 외에도 Mock 서버라는 유용한 기능을 지원함.
실무 팁 - 데이터 샘플을 엑셀 파일로 만든 후 JSON 으로 변환하여 (컨버터 프로그램 사용)
제공받은 데이터를 mock 서버에 등록한 후 개발을 지체 없이 진행할 수 있음.
-> 추후에 데이터셋에 대한 endpoint를 서버주소로 변경하면 됨.
아래 사진대로 진행함.
mock server 생성 (path = test)
example을 default로 설정하고, Body 부분에 JSON 포맷의 데이터를 넣음.
-> Save 버튼 누르면 해당 mock 서버 내에 test라는 API가 추가된 것.
컬렉션 Run
콘솔창을 열면 각 API 호출에 대한 URL을 확인할 수 있음.
Axios
로 API 호출 메서드를 개발.$ yarn add axios
참고로
yarn add
는npm install --save
와 같다.
Axios에서 요청 메서드는 아래와 같다.
1. axios.request(config)
2. axios.get(url[,config])
3. axios.post(url[, data, config])
4. axios.delete(url[,config])
5. axios.put(url[, data, config])
6. axios.patch(url[, data, config])
7. axios.options(url[,config])
8. axios.head(url[,config
= 서버와 통신시 현재 통신하는 목적이 무엇인지 명확하게 전달하게 하기 위해서.
🙋♂️ 왜 Mixin을 쓰는가?
- 다수의 컴포넌트에서 공통으로 사용하는 함수를 구현해야 할 때,
Vue에서는mixin
을 통해 구현하여 사용할 수 있음.- 공통 함수를 구현해서 각 컴포넌트에서 호출해서 사용하는 것이 훨씬 효율적임.
- 각 컴포넌트에서 함수를 별도로 구현했다면 프로그램 내부의 로직 변경 또는 에러 수정 등 변경사항 발생시전체를 바꿔야 하는 위험성이 있음.
src/mixins.js 생성
import axios from 'axios';
export default {
methods: {
async $api(url, method, data) {
return (
await axios({
method: method,
url,
data,
}).catch((e) => {
console.log(e);
})
).data;
},
},
};
src/main.js 수정
import { createApp } from 'vue';
import App from './App.vue';
import router from './router';
import mixins from './mixins';
import { apply } from 'core-js/fn/reflect';
// createApp(App).use(router).mixin(mixins).mount('#app');
const app = createApp(App);
app.use(router);
app.mixin(mixins);
app.mount('#app');
src/views/DataBindingList.vue
<template>
<div>
<table>
<thead>
<tr>
<th>이름</th>
<th>나이</th>
<th>성별</th>
</tr>
</thead>
<tbody>
<tr :key="i" v-for="(person, i) in personList">
<td>{{ person.person_name }}</td>
<td>{{ person.age }}</td>
<td>{{ person.gender }}</td>
</tr>
</tbody>
</table>
</div>
</template>
<script>
export default {
data() {
return {
personList: [],
};
},
created() {
// 라이프 사이클 훅에 의해 getList 실행
this.getList();
},
methods: {
async getList() {
// mixin으로 설정해둔 $api 함수를 사용(this) -> get으로 가져온 값을 this.personlist로 대입
this.personList = await this.$api(
'https://5604e27b-c8b9-48b0-98a9-c4a272c9456b.mock.pstmn.io/list',
'get'
);
},
},
};
</script>
<style scoped>
table {
width: 100%;
border-collapse: collapse;
}
td,
th {
border: 1px solid #666;
text-align: left;
padding: 8px 15px;
}
</style>
+) App.vue와 router/index 수정하기.
컴포넌트 생성 -> created 함수 실행 (라이프사이클 훅) -> async getList -> await $api -> async - awiat axios(method, url, data)
data는 POST 요청일때만 작성하면 된다. (지금은 GET 요청이니 비워둠)
-> await axios()의 결과는 response객체이다.
-> $api 함수는 return (await axios()).data 이므로 response.data를 리턴함.
<tr :key="i" v-for="(person, i) in personList">
<td>{{ person.person_name }}</td>
<td>{{ person.age }}</td>
<td>{{ person.gender }}</td>
</tr>
-> v-for
을 이용한 배열(=리스트) 렌더링.
+) 참고로, personList는 배열이 아닌 Proxy 타입이다!
- Proxy 란? - MDN 문서 참고
-> 참고로, 데이터(객체)는 [[Target]]이라는 프로퍼티 내에 존재한다.
components/PageTitle.vue
<template>
<h2>PageTitle</h2>
</template>
pages/NestedComponent.vue
<template>
<div>
<PageTitle />
</div>
</template>
<script>
import PageTitle from '../components/PageTitle.vue';
export default {
components: { PageTitle },
};
</script>
- import 함
- export - components : { 컴포넌트명 }
- template에서 사용
부모 컴포넌트에서 자식 컴포넌트로 props (데이터) 전달
PageTitle.vue 수정
<template>
<h2>{{ title }}</h2>
</template>
<script>
export default {
props: {
title: {
type: String,
default: '페이지 제목입니다.',
},
},
};
</script>
vues/NestedComponent.vue 수정
<template>
<div>
<PageTitle title="props를 전달할 수 있음" />
</div>
</template>
<script>
import PageTitle from '../components/PageTitle.vue';
export default {
components: { PageTitle },
};
</script>
<PageTitle title="props를 전달할 수 있음" />
<page-title :title="title" />
data() {
return {
title: '동적 타이틀'
};
}
v-bind
를 통해서만 전달해야 함. (아니면 문자열 취급)<blog-post likes="42" />
<!--문자열 취급-->
<blog-post :likes="42" />
v-bind
를 통해서 전달. (:)<blog-post :is-loading="true" />
v-bind
를 사용하지 않으면 문자열로 전달됨.<blog-post :comment-id="[234, 567, 890]" />
<blog-post :comment-id="post.idArrays" />
v-bind
를 사용해야 함<blog-post v-bind="post />
<blog-post :id="post.id" :title="post.title" />
props: {
propA: Number,
propB: [String, Number],
propC: { type: String, required: true },
propD: {
type: Object,
default: function () {
return { message: 'hello' };
},
},
propE: {
validator: function (value) {
return ['success', 'warning', 'danger'].indexOf(value) !== -1;
},
},
}