사진과코딩

[Vue.js] Composition API 본문

KB IT's Your Life

[Vue.js] Composition API

Dev_Fuji 2024. 5. 31. 00:33

Composition API

  • Vue3에서 추가된 기술
  • 기존의 Vue2의 Option API방식은 data,methods,computed가 컴포넌트 별로 분리되지 않고 섞여서 기술.
  • Vue3는 data,methods,computed을 setup() 함수에서 한 번에 정의할 수 있다.
  • instance 생성 시 컴포넌트에 대한 정의를 명확히 명시하고 구조적으로 기술
  • 재사용성을 높이는 기술

 - Vue2 Open API

export default{
    data(){
        return{
            count:0
        }
    },
    methods:{
        increment(){
            this.count++;
        }
    },
    mounted(){
        console.log(this.count);
    }
}

 - Vue3 Composition API

import {ref} from 'vue' ;// composition api 사용

export default{
    setup(){ // methods + data + computed
        const count= ref(0);  //composition import 해야 사용 가능
        const plus =()=>{
            count.value++; //count가 객체 타입이여서 .value를 통해 값을 불러 와야한다.
        }
        function plus2(){
            count.value++; //위와 동일
        }
        return { //proxy로 등록할 객체들 정의
            count,plus,plus2 //function도 내보내줘야 적용이 된다.
        }
    },    
}

 

Composition API - setup()

 

  • <script setup> 을 통해 setup()을 사용하지 않고 <script> 자체를 setup으로 쓸 수 있다.
  • data,methods,computed의 초기화를 담당
  • return 정의를 통해 template에서 사용
  • 반응형 함수로 ref(), reactive() 사용
  • ref()는 기본형 값의 반응성을 가진 참조형 데이터 생성 시 사용
    1. ()를 통해 값을 초기화 한다.
    2. 생성된 참조형 데이터는 setup() 내에서도 사용 가능하다.
    3. 데이터에 접근하기 위해서는 .vlaue()를 이용해서 접근 가능하다 => object 타입이라서
  • reactive()는 객체 리터럴(key:value, key:value , key:value ...)의 참조형 데이터를 생성한다
    1. 객체의 일부만 return 하는 경우 반응성은 적용되지 않는다.
    2. computed()를 통해 계산된 결과값을 접근하려면 .value를 사용해야한다.
<!-- ref:단일데이터 -->
<template>
    <button @click="increment">숫자 :{{ count }}</button>
    <button @click="increment">숫자 :{{ count.num }}</button>
</template>

<script setup>// setup()과 같은 효과
    import { ref, onMounted } from 'vue'; 
    const count = ref(0); //객체 or 원시데이터
    const count = ref({ num: 0, message: "count생성" }); //객체 or 원시데이터

    function increment() {
        count.value++;
        count.value.num++;
    }
    onMounted(() => { //onMounted를 import해야 사용할 수 있다.
        console.log(`숫자의 초기값은${count.value}입니다.`);
    })
</script>

<!-- reactive : 다수의 데이터 -->

<template>
    <button @click="increment">{{count.message}} 숫자 :{{ count.num }}</button>
</template>

<script setup>
import { reactive, onMounted } from 'vue';
const count = reactive({ num: 0, message: "count생성" });

function increment() {
    count.num++;
}
onMounted(() => {
    console.log(`숫자의 초기값은${count.num}입니다.`);
})
console.log("시작")
</script>

 

Composition API - watch

  • Option API의 watch 옵션과 동일
  • watch(data,(current,old)){}를 사용하여 정의
  • 여러개의 값을 정의할 수 있다.
  • reactive() 객체를 watch 설정시 명확히 설정해야한다 => reactive 객체를 설정하면 객체의 모든 값에 watch가 동작
    => 불필요한 실행이 발생한다. 
    => reactive의 데이터를 부를 경우 testwatch.t1이라고 부르면 오류가 발생하므로 ()=>testwatch.t1 처럼 함수를 이용하여 호출하여야 한다.
  • watchEffect에 전달하는 콜백 메소드 안에 반응성을 가진 데이터를 사용하는 경우에만 호출
<script setup>
import { reactive, ref, watch } from 'vue';
const count = ref(0)
const count2 = ref(1)
const testwatch = reactive({"t1" : 10, "t2" : 20});
watch(testwatch,(current,old))=>{ //t1,t2 모두 포함이라 t2의 변화에도 동작 => testwatch를 ()=>testwatch.t1라고 명명해야한다
    console.log(current.x +" "+old.x);
    testwatch.t2 = t1*2;
}
watch([()=>testwatch.t1,()=>testwatch.t2],([currentt1,currentt2],[oldt1,oldt2]))=>{ 
    console.log(current.x +" "+old.x);
    testwatch.t2 = t1*2;
}
watchEffect(() => { console.log('[count, count2] watchEffect', count.value, count2.value) })
// count 또는 count2가 변경되는 경우 호출
</script>
<script>
import { reactive, ref, watch } from 'vue';

export default {
  name: 'FlowerOrder',
  setup() {
    const order = reactive({
      flowerName: '',
      flowerPrice: 0,
      flowerQuantity: 0
    });
    const isOrderPlaced = ref(false);
    const flowerImage = ref('');
    const totalPrice = ref(0);
    const flowerImages = {
      sun: 'https://cdn.pixabay.com/photo/2018/08/29/22/52/sunflowers-3640938_1280.jpg',
      rose: 'https://cdn.pixabay.com/photo/2016/08/03/14/24/roses-1566792_1280.jpg',
    };
    const placeOrder = () => {
      isOrderPlaced.value = true;
      flowerImage.value = flowerImages[order.flowerName.toLowerCase()] || '';
    };
    watch(
        () => [order.flowerPrice, order.flowerQuantity],
        () => {
          totalPrice.value = order.flowerPrice * order.flowerQuantity;
        }
    );
    return {
      order,
      isOrderPlaced,
      flowerImage,
      placeOrder,
      totalPrice
    };
  }
};
</script>

 

구분 watch watchEffect
감시 대상 지정 필요 불필요, 핸들러 함수 내부에서 이용하는 반응성 데이터가 변경되면 함수 실행
  • watchEffect는 watchEffect에 전달하는 콜백 메소드 안에 반응성을 가진 데이터를 사용하는 경우에만 호출됩니다.
변경전 값 이용 가능 이용 불가, 현재값만 필요할 때 사용
감시자 설정후 즉시 실행 즉시 실행 X 즉시 실행