본문 바로가기
Study/Vue

Vue 3 ) 반응형 api 를 이용해보자

by JongIk 2022. 1. 14.
반응형

반응형 기초


아래 글을 읽고 오시면 이해가 더욱 편합니다.

반응성과 관련된 APIs
ref, refs 란??


반응형 상태 선언하기

JavaScript 객체에서 반응형 상태를 생성하기 위해, reactive method 를 사용할 수 있습니다.

import { reactive } from 'vue'
// 반응형 상태
const state = reactive({
  count: 0
})

reactive 는 Vue 2 버전에서의 Vue.observable() API 와 동일한 것으로, RxJS 의 observables 과 혼동을 피하기 위해 이름을 바꿨습니다.
여기서 반환된 상태는 반응형 객체입니다. 반응형 변환은 "deep" - 전달된 객체의 모든 중첩된 속성 (property) 에 영향을 미친다는 의미입니다.

Vue 에서 반응형 상태를 위해 필수로 사용하는 사례는 렌더링 중에 사용할 수 있다는 것입니다. 종속성 추적 (dependency tracking) 덕분에, 반응형 상태가 변경될 때 화면은 자동적으로 업데이트 될 것입니다.

이것을 Vue 반응형 시스템의 본질이라고 합니다. 컴포넌트의 data() 에서 객체를 반환할 때, 이것은 내부적으로 reactive() 에 의해 반응형으로 만들어집니다. 템플릿은 이러한 반응형 속성을 사용하는 렌더 함수로 컴파일됩니다.


refs 로 독립적인 반응형 값 생성하기

독립적인 원시 값 (예를 들어, 문자열 하나) 를 가지고 있고, 이것을 반응형으로 만들고자 할 때, 하나의 문자열을 속성으로 가지는 객체를 만들어서 그것을 reactive 로 던질 수도 있습니다.
하지만 Vue 에서는 ref 를 이용할 수 있습니다.

import { ref } from 'vue'

const count = ref(0)

ref 는 반응형이면서 변이가능한 (mutable) 객체를 반환합니다. 현재 갖고 있는 내부의 값에 대한 반응형 참조 (reference) 의 역할을 합니다.
이 객체는 오직 value 라는 하나의 속성만 포함합니다.

import { ref } from 'vue'

const count = ref(0)
console.log(count.value) // 0

count.value++
console.log(count.value) // 1

Ref Unwrapping

ref 가 렌더 컨텍스트 (setup() 에서 반환된 객체) 에서 속성으로 반환되고 템플릿에서 접근되면, 자동적으로 내부 값을 풀어냅니다.
즉, 템플릿에서 .value 를 추가할 필요가 없습니다.

<template>
  <div>
    <span>{{ count }}</span>
    <button @click="count ++">카운트 증가</button>
  </div>
</template>

<script>
  import { ref } from 'vue'
  export default {
    setup() {
      const count = ref(0)
      return {
        count
      }
    }
  }
</script>

반응형 객체에서의 접근

  • ref 가 반응형 객체의 속성으로 접근하거나 변이될 때, 자동적으로 내부 값으로 벗겨내서, 일반적인 속성과 마찬가지로 동작합니다.
const count = ref(0)
const state = reactive({
  count
})

console.log(state.count) // 0

state.count = 1
console.log(count.value) // 1
  • 만약 새로운 ref 가 기존에 있던 ref 에 연결된 속성에 할당되면, 기존 ref 를 대체하게 됩니다.
const otherCount = ref(2)

state.count = otherCount
console.log(state.count) // 2
console.log(count.value) // 1
  • ref 포장 풀기는 반응형 Object 내부에서 중첩된 경우에만 발생합니다. ref 가 Array나 Map 과 같이 표준 내장 컬렉션 타입에서 접근된 경우에는 Unwrapping 이 동작하지 않습니다.
const books = reactive([ref('Vue 3 Guide')])
// 여기에는 .value 가 필요합니다.
console.log(books[0].value)

const map = reactive(new Map([['count', ref(0)]]))
// 여기에는 .value 가 필요합니다.
console.log(map.get('count').value)

반응형 상태 구조 분해하기 (Destructuring)

  • 큰 반응형 객체의 몇몇 속성을 사용하길 원할 때, 속성을 얻기 위해 ES6 구조 분해 할당을 사용하는 것이 좋다고 생각할 수 있습니다.
import { reactive } from 'vue'

const book = reactive({
  author: 'JongIk',
  year: '2022',
  title: 'Vue 3',
  description: 'Vue King',
  price: '000'
})

let { author, title } = book
  • 하지만 ES6 구조 분해 할당을 사용하면 두 속성은 반응형을 잃게 됩니다. 이 경우에는 반응형 객체를 일련의 ref 들로 변환해야 합니다. ref 들은 소스 객체에 대한 반응형 연결을 유지합니다.
import { reactive, toRefs } from 'vue'

const book = reactive({
  author: 'JongIk',
  year: '2022',
  title: 'Vue 3',
  description: 'Vue King',
  price: '000'
})

let { author, title } = toRefs(book)

title.value = 'Vue 3' // title 이 ref 이므로 .value 를 사용해야 합니다.
console.log(book.title) // 'Vue 3'

readonly 를 이용하여 반응형 객체의 변이 방지하기

  • 때때로 반응형 객체 (ref 나 reactive ) 의 변화를 추적하기를 원하지만, 특정 부분에서는 변화를 막기를 원하기도 합니다.
  • 예를 들어, 제공된 반응형 객체를 갖고 있을 때, 우리는 그것이 주입된 곳에서는 해당 객체가 변이되는 걸 막고자 할 것입니다. 이렇게 하려면 원래 객체에 대한 읽기 전용 프록시를 생성하십시오.
import { reactive, readonly } from 'vue'

const original = reactive({ count: 0 })

const copy = readonly(original)

// 원본이 변이되면 복사본에 의존하는 watch 도 트리거될 것 입니다.
original.count++

// 복사본을 변이하려고 하면 경고와 함께 실패할 것 입니다.
copy.count++ // warning: "Set operation on key 'count' failed: target is readonly."

참고문서 : Vue 3 공식문서

반응형

댓글