암스테르담 Vue.js 컨퍼런스에서 1Q 말에 출시할 예정이고, 2Q 말에 최종 버전을 발표할 예정이라고 발표했습니다.
Vue.js 3에 도입되는 컴포넌트 로직을 유연하게 구성할 수 있는 API 모음입니다.
기존의 Options API를 사용하여 여러 혼재된 논리 구조를 분리하고 재사용 가능하게 하는것이 목적입니다.
We acknowledge the creativity of React Hooks, and it is a major source of inspiration for this proposal. (우리는 React Hooks의 창의성을 인정하며, 이 제안의 주요 영감원이다.)
<template>
<button @click="increment">
Count is: {{ state.count }}, double is: {{ state.double }}
</button>
</template>
<script>
import { reactive, computed } from 'vue'
export default {
setup() {
const state = reactive({
count: 0,
double: computed(() => state.count * 2)
})
function increment() {
state.count++
}
return {
state,
increment
}
}
}
</script>
반응형 상태와 부수효과를 만드는 방법입니다.
watchEffect
는 함수를 즉시 실행하고, 사용한 모든 반응 상태 속성을 종속성으로 추가하여 추적합니다.
state.count
가 변경되면 내부 함수가 다시 실행됩니다.
import { reactive, watchEffect } from 'vue'
const state = reactive({
count: 0
})
watchEffect(() => {
document.body.innerHTML = `count is ${state.count}`
})
reactive는 Vue 2.x API에 있는 Vue.observable()과 동일합니다.
computed
computed
로 다른 상태에 의존하는 계산된 속성을 만들 수 있습니다.
다만 reactive
와 다르게 computed
는 ref
를 사용하기 때문에, .value
를 통해 값을 접근해야 합니다.
const double = computed(() => state.count * 2)
watchEffect(() => {
console.log(double.value)
}) // -> 0
state.count++ // -> 2
ref
ref
는 primitive type을 가변 참조 객체로 만들고, 내부 값을 가리키는 단일 속성 value
가 있습니다.
import { ref, watch } from 'vue'
const count = ref(0)
function increment() {
count.value++
}
reactive
reactive
는 객체를 반응형으로 만듭니다.
import { reactive } from 'vue'
const state = reactive({
count: 0
})
function increment() {
state.count++
}
객체를 사용하는 경우 reactive
를 사용하면 되지만, 반환된 객체에 대한 참조유지를 위해 객체를 해제하거나 펼치는 경우 toRefs()
를 사용합니다.
const state = reactive({
count: 0
})
const { count } = state // 반응성 손실, 값 변경시 재렌더링 동작 안함.
const state = reactive({
count: 0
})
const stateAsRefs = toRefs(state);
const { count } = stateAsRefs // 반응성 유지
/*
Type of stateAsRefs:
{
count: Ref<number>,
}
*/
기본적으로 Composition API는 컴포넌트 컨텍스트 외부에서 사용할수 있고, 컴포넌트 인스턴스에서 사용할 수도 있습니다. 컴포넌트 내부에서는 setup()
함수에서 초기화 부분을 선언합니다. setup()
함수는 beforeCreate
이전에 호출됩니다.
<template>
<button @click="increment">
Count is: {{ state.count }}, double is: {{ state.double }}
</button>
</template>
<script>
import { reactive, computed } from 'vue'
export default {
setup() {
const state = reactive({
count: 0,
double: computed(() => state.count * 2)
})
function increment() {
state.count++
}
return {
state,
increment
}
}
}
</script>
상태 변화에 따라 부수효과를 적용하는 것은 watchEffect
와 watch
API를 사용하고, 기존의 라이프 사이클 훅은 onXXX
API 형태로 사용할 수 있습니다.
use setup()
use setup()
onBeforeMount
onMounted
onBeforeUpdate
onUpdated
onBeforeUnmount
onUnmounted
onErrorCaptured
새로 추가된 항목
중복되는 논리를 추출하여 재사용 가능하도록 만들 수 있습니다.
Counter 애플리케이션을 작성하는 경우, 증감 부분을 분리하여 재사용 할 수 있습니다.
/* use ref */
export function useCount() {
const count = ref(0);
const increment = () => ++count.value;
const decrement = () => --count.value;
return { count, increment, decrement };
}
/* use reactive */
export function useCount() {
const stateAsRefs = reactive({ count: 0 });
const increment = () => ++stateAsRefs.count;
const decrement = () => --stateAsRefs.count;
const { count } = toRefs(stateAsRefs);
return { count, increment, decrement };
}
<template>
<div>
<h3>Number is: {{ count }}</h3>
<button class="myButton" @click="increment">Increment</button>
<button class="myButton" @click="decrement">Decrement</button>
</div>
</template>
<script>
import { useCount } from "@/hooks/useCount";
export default {
setup() {
const { count, increment, decrement } = useCount();
return {
count,
increment,
decrement
};
}
};
</script>
재사용 로직을 분리하여 모아놓은 vue-hooks를 사용할 수도 있습니다.
리액트와 비교
암스테르담 2020
Vue3 소개