Vue3 - 반응형 기초 (Reactivity)
## 반응형 상태 선언하기
Javascript 객체에서 반응형 상태를 생성하기 위해서는 reactive() 함수를 사용할 수 있습니다.
import { reactive } from 'vue';
// 반응형 상태
const state = reactive({ count: 0 })
컴포넌트 <template> 에서 반응형 객체를 사용하려면 setup() 함수에서 선언하고 리턴해야 합니다.
- 반환된 상태는 반응형 객체 입니다. 반응형 변환은 “깊습니다”
- 컴포넌트의 data()에서 객체를 반환할 때, 이것은 내부적으로 reactive()에 의해 반응형으로 만들어집니다.
import { reactive } from 'vue';
export default {
setup () {
// 반응형 상태
const state = reactive({ count: 0 })
return {
state
}
}
}
ref로 원시값 반응형 데이터 생성하기
reactivity() 함수는 객체타입에만 동작합니다. 그래서 기본타입(number, string, boolean)을 반응형으로 만들고자 할 때 ref 메소드를 사용할 수 있습니다.
(예제)
import { ref } from 'vue'
const count = ref(0)
ref 메서드는 변이가능한(mutable) 객체를 반환합니다. 이 객체 안에는 value라는
하나의 속성만 포함하는데요. Value 값은 ref() 메서드에서 매개변수로 받은 값을
갖고 있습니다. 이 객체는 내부의 value 값에 대한 반응형 참조(reference)
역할을 합니다.
(예제)
import { ref } from 'vue'
const count = ref(0)
console.log(count.value) // 0
count.value++
console.log(count.value) // 1
### 반응형 객체의 ref Unwarpping
ref가 반응형 객체의 속성으로 접근할 때, 자동적으로 내부 값으로 벗겨내서, 일반적인 속성과 마찬가지로 동작합니다.
이때 반응형은 연결되어 있습니다.
(예제)
import { reactive, ref } from 'vue'
export default {
setup() {
const count = ref(0);
const state = reactive({
count,
});
count.value++;
count.value++;
console.log(count.value);
console.log('state.count: ', state.count)
return {};
}
}
### 배열 및 컬렉션의 참조 Unwarpping
반응형 객체와 달리 ref가 반응형 배열 또는 Map과 같은 기본 컬렉션 타입의 요소로 접근될 때 수행되는 래핑 해제가 없습니다.
- 배열은 arr[0].value 즉, value를 붙여주는 것이 관건이다.
(예제)
import { reactive, ref } from 'vue'
export default {
setup() {
// ref -> Object
const count = ref(0);
const state = reactive({
count,
});
count.value++;
count.value++;
// console.log(count.value);
// console.log('state.count: ', state.count);
// ref -> Array
const message = ref('Hello');
const arr = reactive([message]);
console.log('arr[0]: ', arr[0].value);
return {};
}
}
### 반응형 상태 구조 분해하기 (Destructuring)
큰 반응형 객체의 몇몇 속성을 사용하길 원할 때, 원하는 속성을 얻기 위해 ES6 구조 분해 할당을 사용하는 것은 매우 일반적 입니다.
(예제)
import { reactive } from 'vue'
const book = reactive({
auth: 'Vue Team',
year: '2020',
title: 'Vue 3 Guide',
description: '당신은 이 책을 지금 바로 읽습니다;',
price: '무료'
})
let { author, title } = book
안타깝게도 , 그러한 구조 분해로 두 속성은 반응형을 잃게 될 것 입니다. 이런 경우, 반응형 객체를 일련의 ref로 변환해야 합니다.
이러한 ref 들은 소스 객체에 대한 반응형 연결을 유지합니다.
toRefs, toRef를 사용하면 반응형 객체의 속성과 동기화 됩니다. 그래서 원본 속성을 변경하면 ref 객체가 업데이트 되고
그 반대의 경우도 마찬가지 입니다.
(예제)
import { reactive } from 'vue'
export default {
setup () {
const book = reactive({
author: 'Vue Team',
year: '2020',
title: 'Vue 3 Guide',
description: '당신은 지금 바로 이 책을 읽습니다.',
price: '무료',
});
const { author, title } = book;
console.log(typeof author);
return { author, title, book };
}
}
- 반응성을 잃어버리지 않으면서 구조분해 할당은 할 수 없을까 ?
- 그 방법은 있다! toRefs!, toRef!!
(예제)
<template>
<div>
<p>author: {{ author }}</p>
<p>title: {{ title }}</p>
</div>
</template>
<script>
import { reactive, toRef, toRefs } from 'vue'
export default {
setup () {
const book = reactive({
author: 'Vue Team',
year: '2020',
title: 'Vue 3 Guide',
description: '당신은 지금 바로 이 책을 읽습니다.',
price: '무료',
});
// const { author, title } = toRefs(book);
const author = toRef(book, 'author');
const title = toRef(book, 'title');
return { author, title, book };
}
}
</script>
### readonly를 이용하여 반응형 객체의 변경 방지
때때로 반응형 객체(ref 나 reactive)의 변화를 추적하기 원하지만, 또한 특정 부분에서는 변화를 막기 원하기도 합니다.
예를 들어, Provide/Inject로 주입된 반응형 객체를 갖고 있을때, 우리는 그것이 주입된 곳에서는 해당 객체가 변이되는걸 막고자 할 것입니다.
이렇게 하려면 원래 객체에 대한 읽기 전용 프록시를 생성하십시오 .
Reactivity Transform 실험적인 단계
refs와 함께 .value를 사용해야 하는 것은 Javascript의 언어 제약으로 인한 단점입니다.
그러나 compile-time transforms($ref()) 을 사용하면 적절한 위치에 .value를 자동으로 추가하여
인체 공학을 개선할 수 있습니다.
Vue는 다음과 같이 이전 “counter” 예제를 작성할 수 있는 compile-time transforms을 제공합니다.
<template>
<button @click="increment">{{ count }}</button>
</template>
<script setup>
let count = $ref(0)
function increment() {
// no need for .value
count++
}
</script>