TIL 22-06-03

thisisyjin·2022년 6월 3일
0

TIL 📝

목록 보기
58/113

Vue.js

Today I Learned ... Vue.js

🙋‍♂️ Reference Book


DAY 04 - 220603
-9. Composition API
-10. Proxy 사용

Composition API

✅ 컴포지션 API 란?

컴포넌트 내에서 사용하는 특정 기능을 갖는 코드를 유연하게 구성하여 사용하게 하는
함수 기반 API.
-> Vue 3 버전의 핵심 기능임.

  • Vue는 프로젝트 규모가 커질수록 (data, computed, watch, methods 등) or
    계층 구조가 복잡할수록 코드 추적 및 관리가 어려웠음.
    -> 컴포지션 API를 이용하면 Setup 이라는 메서드 내에서 한덩어리로 코드를 구현할 수 있음.
  • 특정 기능을 갖는 함수를 정의하고, API처럼 사용할 수 있게 해주는 것임.
  • 코드 재활용성 / 가독성을 높이기 위해 추가된 기능.

❗️ Vue 2에서는 mixin(믹스인)을 통해 코드를 재사용했지만, 오버라이딩 문제 등으로 관리가 어려웠음.

Setup

  • 컴포지션 API를 구현하는 곳.

📝 예제 - 사용자로부터 숫자 두개를 입력받고, 둘을 더한 값을 출력하는 코드.

<template>
  <div>
    <h2>Calculator</h2>
    <div>
      <input type="number" v-model="num1" @keyup="plusNumbers" />
      <span> + </span>
      <input type="number" v-model="num2" @keyup="plusNumbers" />
      <span> = </span>
      <span>{{ result }}</span>
    </div>
  </div>
</template>

<script>
export default {
  // eslint-disable-next-line vue/multi-word-component-names
  name: 'calculator',
  data() {
    return {
      num1: 0,
      num2: 0,
      result: 0,
    };
  },
  methods: {
    plusNumbers() {
      this.result = this.num1 + this.num2;
    },
  },
};
</script>

-> keyup 이벤트가 발생할 때 마다 두 수를 더하여 result 값을 반환함.


컴포지션 ver.

위와 동일한 기능을 하는 코드를 컴포지션 API를 이용하여 구현하면

1) reactive

<template>
  <div>
    <h2>Calculator</h2>
    <div>
      <input type="number" v-model="state.num1" @keyup="plusNumbers" />
      <span> + </span>
      <input type="number" v-model="state.num2" @keyup="plusNumbers" />
      <span> = </span>
      <span>{{ state.result }}</span>
    </div>
  </div>
</template>

<script>
import { reactive } from 'vue';
export default {
  // eslint-disable-next-line vue/multi-word-component-names
  name: 'calculator',
  setup() {
    let state = reactive({
      num1: 0,
      num2: 0,
      result: 0,
    });

    function plusNumbers() {
      state.result = state.num1 + state.num2;
    }

    return {
      state,
      plusNumbers,
    };
  },
};
</script>

reactive

import { reactive } from 'vue';

vue의 reactive를 임포트해서 실시간 변경사항에 대한 반응형 적용.

return { state, plusNumbers }

  • setup 내에서 let state = reactive({});
    function plusNumbers(){}로 선언함.

  • state, plusNumbers를 반환함으로써
    기존에 data, methods 옵션 처럼 템플릿에서 사용 가능하도록 함.


2) computed

import { reactive, computed } from 'vue'; // 👈 computed 임포트

...

setup() {
    let state = reactive({
      num1: 0,
      num2: 0,
      result: computed(() => state.num1 + state.num2), // num1, num2 변경시 즉시  더한 값을 result로 반환
    });

    return {
      state,
    };
  },

computed

  • computed()안에는 콜백이 들어감.
  • 내부에 들어간 값을 관찰하고, 리턴값을 해당 변수로 반환함.
computed: {
  fullName() {
    return this.firstName + this.lastName;
  }
}

🔺 기존 computed 옵션 사용법

🔻 setup 내에서 사용시 (컴포지션 API)

// setup 내에서 사용시
fullName: computed(() => state.firstName + state.lastName)

3) toRefs

  • 현재 컴포넌트 말고 다른 컴포넌트에서도 사용할 수 있게 함수를 분리.
<template>
  <div>
    <h2>Calculator</h2>
    <div>
      <input type="number" v-model="num1" />
      <span> + </span>
      <input type="number" v-model="num2" />
      <span> = </span>
      <span>{{ result }}</span>
    </div>
  </div>
</template>

<script>
import { reactive, computed, toRefs } from 'vue';
function plusCalculator() {
  let state = reactive({
    num1: 0,
    num2: 0,
    result: computed(() => state.num1 + state.num2),
  });

  return toRefs(state); // 외부 컴포넌트에서 num1, num2, result가 정상 동작하게 해줌
}
export default {
  // eslint-disable-next-line vue/multi-word-component-names
  name: 'calculator',
  setup() {
    let { num1, num2, result } = plusCalculator();
    return {
      num1,
      num2,
      result,
    };
  },
};
</script>

LifeCycle Hooks

컴포지션 API 내에서 사용할 수 있는 라이프사이클 훅.

created / beforeMount / mounted / beforeUpdate / updated / beforeUnmount unmounted 등

setup() -> beforeCreate와 created 사이에서 실행됨.


Provide / Inject

  • provide와 inject를 별도로 임포트 해야 사용 가능.
  • 부모 컴포넌트에서는 provide 함수를 통해 전달할 값의 Key-value를 설정함.

부모 컴포넌트

<template>
  <CompositionInject />
</template>

<script>
import { provide } from '@vue';

import CompositionInject from './CompositionInject';

export default {
  components: {
    CompositionInject,
  },
  setup() {
    provide('title', 'Vue.js 프로젝트'); // provide 함수 : key-value 쌍으로 전달할 값 설정
  },
};
</script>

자식 컴포넌트

<template>
  <h1>{{ title }}</h1>
</template>

<script>
import { inject } from 'vue';
export default {
  setup() {
    const title = inject('title'); // key값으로 가져옴
    return { title };
  },
};
</script>

Mixins

자주 사용되는 기능을 메서드로 만들어 등록해놓고, 모듈을 import 하듯이
Vue에서도 mixin을 통해 가능함.

믹스인 이란?

  • 기능은 따로 구현하고, 필요할 때 마다 믹스이 파일을 컴포넌트에 결합하여 사용하는 방법.

예제 - Mock 서버의 API를 호출하는 믹스인.

믹스인 파일 생성

src/api.js 생성

import axios from 'axios';

export default {
  methods: {
    async $callAPI(url, method, data) {
      return (
        await axios({
          method: method,
          url,
          data,
        }).catch((e) => {
          console.log(e);
        })
      ).data;
    },
  },
};

컴포넌트에서 믹스인 사용

views/Mixins.vue 생성

<script>
import ApiMixin from '../api.js';

export default {
  mixins: [ApiMixin],
  data() {
    return {
      personList: [],
    };
  },
  async mounted() {
    this.personList = await this.$callAPI(
      'https://5604e27b-c8b9-48b0-98a9-c4a272c9456b.mock.pstmn.io/list',
      'get'
    );
    console.log(this.personList);
  },
};
</script>
  • 위와 같이 mounted 같은 라이프사이클 훅을 async-awiat으로 작성 가능함.
    -> axios.get은 비동기이므로

  • Mixin에서 methods로 등록한 함수를 this.$callAPI와 같이 사용 가능함.

profile
기억은 한계가 있지만, 기록은 한계가 없다.

0개의 댓글