Composition API의 활용
Composition API 란?
: 대규모 Vue 애플리케이션에서의 컴포넌트 로직을 효과적으로 구성하고 재사용할 수 있도록 만든 함수 기반 API
setup 메서드를 이용한 초기화
- 기존 옵션 API의 생명주기와 비교하자면 beforeCreate, created 단계에서 setup() 메서드 호출
- setup 메서드 내부에서 작성한 데이터나 메서드를 템플릿에서 이용하고 싶다면 객체 형태로 리턴
- setup() 메서드는 2개의 인자 사용
- props : 부모 컴포넌트로부터 전달 받는 속성
- context : 기존 옵션 API 에서 this 컨텍스트가 제공하던 정보, emit( this.$emit ) 등..
<script>
export default {
name: 'App',
setup (props, context) {
return { ... }
}
}
</script>
반응성을 가진 상태 데이터 - ref
- 기본 타입(string, num, boolean ...)의 값을 이용해 반응성을 가진 참조형 데이터 생성
- ref()의 인자로 초기값 부여
<template>
<div>결과 : {{ result }}</div>
</template>
<script>
import { ref } from 'vue'
export default {
name: 'App',
setup () {
const x = ref(10);
const y = ref(20);
const result = ref(30);
const calcAdd = () => {
result.value = x.value + y.value
}
return { x, y, result }
}
}
</script>
- setup() 메서드 내부에서 데이터를 이용할 때는 x.value 와 같이 .value 속성 이용
반응성을 가진 상태 데이터 - reactive
- 객체에 대한 반응성을 가진 참조형 데이터 생성
<template>
<div>결과 : {{ state.result }}</div>
</template>
<script>
import { reactive } from 'vue'
export default {
name: 'App',
setup () {
const state = reactive({ x: 0, y: 0, result: 0 })
const calcAdd = () => {
state.result = state.x + state.y
}
return { state, calcAdd }
}
}
</script>
- reactive() 를 이용해 반응성을 가진 객체의 내부 값을 리턴하여 템플릿에서 바인딩하면 반응성을 잃어버림.
( return { state }가 아니라 return { state.x } 등.. )
반드시 객체 자체를 리턴하여 반응성을 유지하기.
computed
- 옵션 API 에서 computed 옵션을 이용한 것처럼 사용 가능
- computed()에 의해 생성된 데이터는 템플릿에서는 직접 이용가능,
<script></script> 내부에서 사용할 때는 반드시 .value속성을 통해 접근
<template>
<div>결과 : {{ result }}</div>
</template>
<script>
import { reactive, computed } from 'vue'
export default {
name: 'App',
setup () {
const state = reactive({ x: 0, y: 0 })
const result = computed(() => {
return state.x + state.y
})
return { state, result }
}
}
</script>
watch
- 데이터나 속성, computed 값이 변경되면 반응
- 변경되기 전과 후의 값을 모두 확인, 이용 가능
watch(data, (current, old) => { ... })
watch([data1, data2, ...], ([current1, current2, ...], [old1, old2, ...]) => { ... })
- watch()의 첫 번째 인자 : 감지 하려는 대상 (반응성 데이터, 속성, computed 값)
두 번쨰 인자 : 2개의 인자(변경된 값, 변경전 값)를 가지는 handler 함수
<template>
<div>
x : <input type="text" v-model.number="x" />
결과 : {{ result }}
</div>
</template>
<script>
import { ref, watch } from 'vue'
export default {
name: 'App',
setup () {
const x = ref(0);
const result = ref(0);
watch(result, (curret) => {
result.value = current * 2
})
return { x, result }
}
}
</script>
- watch의 첫번째 인자(감지하려는 대상)가 ref()를 이용한 반응성 데이터여도,
두 번째 인자(handler 함수)의 current, old 데이터는 ref.value 값을 가지기 때문에 바로 접근
<template>
<div>
x : <input type="text" v-model.number="state.x" />
결과 : {{ state.result }}
</div>
</template>
<script>
import { reactive, watch } from 'vue'
export default {
name: 'App',
setup () {
const state = reactive({ x: 0, result: 0 })
// 해당 코드로 작성 시, v-model인 x가 변경되어 1차 함수 실행
// x가 변경됨에 따라 result도 변경되어 2차 함수 실행
watch(state, (curret) => {
state.result = current.x * 2
})
// 1차 수정
watch(state.x, (current) => { // ERROR - 감시 대상 데이터는 반응성을 가져야 함
state.result = current * 2
})
// 2차 수정
watch(() => state.x, (current) => { // SUCCESS
state.result = current * 2
})
return { state }
}
}
</script>
- reactive() 를 이용해 생성한 반응성 객체에 대한 설정
- reactive()를 이용해 만든 반응성 데이터 객체 내부의 값의 변경을 감시하는 감시자를 생성하려면
감시 대상을 게터(getter) 함수로 정의
watchEffect
- Vue3에서 반응성 데이터 의존성을 추적하는 기능을 제공하는 새로운 방법
- 감시 대상 지정 없이, 반응성 데이터를 이용하는 핸들러 함수만을 지정.
핸들러 함수 내부에서 사용하는 반응성 데이터 변경시 자동 함수 실행
- watchEffect() 등록 직후 일단 핸들러 함수 최초 실행하고 데이터 변경시 재실행
- watchEffect()에 지정하는 핸들러 함수는 전달하는 인자가 없기 때문에 반응성 데이터 직접 접근
watchEffect(() => { ... })
<template>
<div>
x : <input type="text" v-model.number="x" />
y : <input type="text" v-model.number="y" />
결과 : {{ result }}
</div>
</template>
<script>
import { ref, watchEffect } from 'vue'
export default {
name: 'App',
setup () {
const x = ref(0);
const y = ref(0);
const result = ref(0);
watchEffect(() => {
result.value = x.value + y.value
})
return { x, y, result }
}
}
</script>