javascript 객체에서 반응형 상태를 생성하기 위해서는 reactive() 함수를 사용할 수 있다.
<template>
<div>{{ state.count }}</div>
</template>
import { reactive } from 'vue';
export default {
setup() {
const state = reactive({ count: 0 });
return {
state
}
}
}
참고. Options API에서 data()에서 객체를 반환할때 이것은 내부적으로 reactive()에 의해 반응형으로 만들어진다.
reactive() 함수는 객체타입에만 동작한다. 그렇다면 기본타입(number, string, boolean)을 반응형으로 만들고자 할때는 어떻게하는가? ref()함수를 쓰자.
import { ref } from 'vue';
const counter = ref(0);
ref() 메서드는 객체를 반환한다. 이 객체 안에는 value라는 속성 하나만 포함한다.
즉 ref()는 내부 value 값에 대한 반응형 참조역할을 할 뿐이다.
템플릿에서 사용할때는 자동으로 내부 값(value)를 풀어낸다(unwrap)
<template>
<div>
<span>{{ count }}</span> // count.value 아님!
<button v-on:click="count++">증가</button> // count.value++아님!
</div>
</template>
<script>
import { ref } from 'vue';
export default {
setup() {
const count = ref(0);
return {
count
}
}
}
</script>
ref가 반응형 객체(reactive)의 속성으로 접근할 때, 자동적으로 내부에 값을 벗겨낸다. 코드로 확인하는 것이 확실하다.
const count = ref(0);
const state = reactive({ count })
count.value++;
console.log(count.value) // 1
console.log(state.count) // 1 state.count.value이 아님
반응형 '객체'에서 ref가 속성으로 접근할 때는 자동으로 내부에 값을 벗겨낸다(unwrapping된다.)
But! ref가 반응형 '배열' 또는 'Map'과 같은 기본 컬렉션 타입의 요소로 접근할 때는 unwrapping되지 않는다.
const books = reactive([ref('vue 3 guide')]);
console.log(books[0].value) // .value를 해줘야 한다.
const map = reactive(new Map([['count', ref(0)]]))
console.log(map.get('count').value); // .value 해줘야 한다.
JS개발시 구조분해할당은 자주 일어나는 일이다.
import { reactive } from 'vue';
const book = reactive({
author: 'seojinwoong',
year: '1993',
title: 'my name is seojinwoong',
description: '안녕'
});
let { author, year } = book;
이 경우 author, year는 반응형의 성격을 잃게 된다. 반응형 성격을 유지하려면?
import { reactive } from 'vue';
const book = reactive({
author: 'seojinwoong',
year: '1993',
title: 'my name is seojinwoong',
description: '안녕'
});
let { author, year } = toRefs(book);
author.value = 'kimhoho'; // author이 ref이므로 .value를 붙여서 써야한다.
해당 객체가 변이되는 것을 막고자 할때, readonly를 사용하자
import { reactive, readonly } from 'vue';
const original = reactive({ count: 0 });
const copy = readonly(original);
original.count++;
copy.count++ // 복사본을 변이하려고하면 경고가 나오면서 실패한다.