TIL 22-05-30

thisisyjin·2022년 5월 30일
0

TIL 📝

목록 보기
56/113

Vue.js

Today I Learned ... Vue.js

🙋‍♂️ Reference Book


DAY 03 - 220530

    1. mock 서버
    1. 서버 데이터 바인딩
    1. 컴포넌트 심화

Mock 서버

  • 실제 서버처럼 클라이언트로부터 요청을 받으면 응답하는 가짜 서버.
  • 실제처럼 api를 호출하여 데이터를 받아와서 Vue에서 사용함.

Postman

  • API 개발을 위한 협업 플랫폼.

  • API 테스트, 모니터리으 공유 등의 기능을 함.
    -> 제대로 동작하는지 테스트 용도로 주로 사용됨.

  • 테스트 기능 외에도 Mock 서버라는 유용한 기능을 지원함.

실무 팁 - 데이터 샘플을 엑셀 파일로 만든 후 JSON 으로 변환하여 (컨버터 프로그램 사용)
제공받은 데이터를 mock 서버에 등록한 후 개발을 지체 없이 진행할 수 있음.
-> 추후에 데이터셋에 대한 endpoint를 서버주소로 변경하면 됨.

아래 사진대로 진행함.

mock server 생성 (path = test)

example을 default로 설정하고, Body 부분에 JSON 포맷의 데이터를 넣음.

-> Save 버튼 누르면 해당 mock 서버 내에 test라는 API가 추가된 것.

컬렉션 Run

콘솔창을 열면 각 API 호출에 대한 URL을 확인할 수 있음.


서버 데이터 바인딩

API 호출 메서드 생성

  • 실제 프로젝트에서 모든 데이터를 서버로부터 받고, 발생한 데이터는 서버로 보내서 DB에 저장해야 함.
  • 서버와의 통신에 가장 많이 사용하는 패키지인 Axios로 API 호출 메서드를 개발.

Axios란?

  • 서버와 데이터를 송수신 할 수 있는 HTTP 비동기 통신 라이브러리.
  • Promise 객체 형태로 값을 리턴함. (async/awiat 가능, 구형 브라우저도 지원)
  • 응답 시간 초과시 요청을 종료시킬 수 있는 기능 O.
$ yarn add axios

참고로 yarn addnpm install --save와 같다.

Axios 사용법

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 파일 생성

🙋‍♂️ 왜 Mixin을 쓰는가?

  • 다수의 컴포넌트에서 공통으로 사용하는 함수를 구현해야 할 때,
    Vue에서는 mixin을 통해 구현하여 사용할 수 있음.
  • 공통 함수를 구현해서 각 컴포넌트에서 호출해서 사용하는 것이 훨씬 효율적임.
  • 각 컴포넌트에서 함수를 별도로 구현했다면 프로그램 내부의 로직 변경 또는 에러 수정 등 변경사항 발생시전체를 바꿔야 하는 위험성이 있음.
  • Mock 서버의 API를 호출하는 함수를 Mixins에 등록함.

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');

서버 데이터 렌더링

  • Mock 서버에 API 등록하기
  • 브라우저로 요청시

서버 데이터 호출 및 렌더링

  • Vue 컴포넌트에서 Mock 서버로 API를 호출하여 데이터를 받아온 후, 리스트 렌더링을 해보자.

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 타입이다!

-> 참고로, 데이터(객체)는 [[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>
  1. import
  2. export - components : { 컴포넌트명 }
  3. template에서 사용

props 전달

부모 컴포넌트에서 자식 컴포넌트로 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>

정적 / 동적 Prop 전달

  • 정적 prop 전달
<PageTitle title="props를 전달할 수 있음" />
  • 동적 prop 전달
<page-title :title="title" />

data() {
   return {
      title: '동적 타이틀'
   };
}

숫자형 전달

  • v-bind 를 통해서만 전달해야 함. (아니면 문자열 취급)
<blog-post likes="42" /> 
<!--문자열 취급-->
<blog-post :likes="42" />

Boolean 전달

  • 마찬가지로 반드시 v-bind를 통해서 전달. (:)
<blog-post :is-loading="true" />

배열(Array) 전달

  • 마찬가지로 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 유효성 검사

  • default (기본값) / required (필수 여부) / validator (유효성 검사 함수)
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;
      },
    },
  }
profile
기억은 한계가 있지만, 기록은 한계가 없다.

0개의 댓글