πŸ“— Vue.js

[Vue.js] λ°˜μ‘μ„±(Reactivity) μ‹œμŠ€ν…œ

JaeBBang 2024. 12. 4. 15:32

1. Vue의 λ°˜μ‘μ„± μ‹œμŠ€ν…œμ΄λž€?

κ°„λ‹¨ν•˜κ²Œ λ§μ”€λ“œλ¦¬μžλ©΄, 데이터 μƒνƒœκ°€ λ³€ν•˜λ©΄ μžλ™μœΌλ‘œ μ‚¬μš©μž μΈν„°νŽ˜μ΄μŠ€(UI)에 λ°˜μ˜λ˜λ„λ‘ ν•˜λŠ” μ‹œμŠ€ν…œμ„ λ§ν•©λ‹ˆλ‹€.

 

Vue의 λ°˜μ‘μ„± μ‹œμŠ€ν…œμ€ μ˜΅μ €λ²„ νŒ¨ν„΄(Observer Pattern)에 κΈ°λ°˜μ„ 두고 μžˆμŠ΅λ‹ˆλ‹€.

μ˜΅μ €λ²„ νŒ¨ν„΄μ΄λž€ ?

λ””μžμΈ νŒ¨ν„΄(Design Pattern)쀑 ν•˜λ‚˜λ‘œ, 객체 κ°„ 1 λŒ€ N 관계λ₯Ό μ •μ˜ν•˜μ—¬, ν•œ 객체의 μƒνƒœκ°€ λ³€κ²½λ˜μ—ˆμ„ λ•Œ
μ˜μ‘΄μ„±μ„ κ°€μ§„ λ‹€λ₯Έ κ°μ²΄λ“€μ—κ²Œ μžλ™μœΌλ‘œ μ•Œλ¦Όμ„ μ „λ‹¬ν•˜λŠ” κ΅¬μ‘°μž…λ‹ˆλ‹€.

 

즉, 객체의 μƒνƒœκ°€ 변경이 되면 μ˜μ‘΄μ„±μ„ κ°€μ§„ λ‹€λ₯Έ κ°μ²΄λ“€μ˜ μƒνƒœλ„ 같이 변경을 μ‹œν‚¬ 수 μžˆλ‹€λŠ” λœ»μž…λ‹ˆλ‹€.

 

VueλŠ” 데이터λ₯Ό μΆ”μ ν•˜κ³  데이터 λ³€κ²½ 사항이 κ°μ§€λ˜λ©΄ 이λ₯Ό λ Œλ”λ§ μ‹œμŠ€ν…œ(Renderer)에 전달해 UIλ₯Ό μžλ™μœΌλ‘œ μ—…λ°μ΄νŠΈλ₯Ό ν•˜κ²Œ λ˜λŠ”λ°, 이 과정은 크게 두 λ‹¨κ³„λ‘œ μ΄λ£¨μ–΄μ§‘λ‹ˆλ‹€:

 

  • 데이터 좔적
    • VueλŠ” λ°μ΄ν„°μ˜ μƒνƒœλ₯Ό μΆ”μ ν•˜μ—¬, λ³€κ²½ 사항을 κ°μ§€ν•˜κ³ , 이λ₯Ό 톡해 데이터와 UI μ‚¬μ΄μ˜ 관계λ₯Ό μœ μ§€ν•©λ‹ˆλ‹€.
  • UI μ—…λ°μ΄νŠΈ
    • 데이터가 λ³€κ²½λ˜λ©΄, VueλŠ” λ³€κ²½λœ 데이터와 μ—°κ²°λœ UIλ₯Ό λ‹€μ‹œ λ Œλ”λ§ν•˜μ—¬ μ‚¬μš©μžμ—κ²Œ μ΅œμ‹  μƒνƒœλ₯Ό λ³΄μ—¬μ€λ‹ˆλ‹€.

 

2. Vue 3μ—μ„œ λ°˜μ‘μ„±μ„ κ΅¬ν˜„ν•˜λŠ” 방법

Vue 3μ—μ„œλŠ” Composition APIλ₯Ό λ„μž…ν•˜μ—¬ λ”μš± μ„Έλ°€ν•˜κ³  μœ μ—°ν•˜κ²Œ λ°˜μ‘μ„±μ„ κ΅¬ν˜„ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

μ£Όμš” κΈ°λŠ₯인 ref와 reactiveλ₯Ό μ€‘μ‹¬μœΌλ‘œ 보도둝 ν•˜κ² μŠ΅λ‹ˆλ‹€.

 

2-1. ref

refλŠ” κΈ°λ³Έ 데이터 νƒ€μž…(숫자, λ¬Έμžμ—΄ λ“±)을 λ°˜μ‘ν˜• λ°μ΄ν„°λ‘œ λ§Œλ“€ λ•Œ μ‚¬μš©λ©λ‹ˆλ‹€.

<template>
  <p>Count: {{ count }}</p>
  <button @click="increment">Increment</button>
</template>
<script setup>
import { ref } from 'vue'
const count = ref(0)

const increment = () => {
  count.value++
}
</script>

 

μš°μ„  ref둜 μƒμ„±ν•œ 값은 .value둜 μ ‘κ·Όν•΄μ•Ό ν•©λ‹ˆλ‹€.

객체에도 refλ₯Ό μ‚¬μš©ν•  수 μžˆμ§€λ§Œ, 객체 전체λ₯Ό ꡐ체할 일이 μ—†λ‹€λ©΄ reactiveλ₯Ό μ‚¬μš©ν•˜λŠ”κ²Œ 더 μ ν•©ν•©λ‹ˆλ‹€.

 

2-2. reactive

reactiveλŠ” 객체(Object)와 λ°°μ—΄(Array)λ₯Ό λ°˜μ‘ν˜•μœΌλ‘œ λ§Œλ“€ λ•Œ μ‚¬μš©λ©λ‹ˆλ‹€.

<template>
  <div>
    <p>Name: {{ user.name }}</p>
    <p>Age: {{ user.age }}</p>
    <button @click="updateName('Jane Doe')">Change Name</button>
  </div>
</template>
<script setup>
import { reactive } from 'vue'
const user = reactive({
  name: 'John Doe',
  age: 30,
})

const updateName = (newName) => {
  user.name = newName
}
</script>

 

reactiveλ₯Ό μ‚¬μš©ν•˜κ²Œ 되면 객체 λ‚΄λΆ€μ˜ λͺ¨λ“  속성이 λ°˜μ‘ν˜•μœΌλ‘œ μ„€μ •λ˜λ©°, κΈ°μ‘΄ 속성을 μ—…λ°μ΄νŠΈν•˜λ©΄ Vueκ°€ 이λ₯Ό 감지해

UIλ₯Ό μ—…λ°μ΄νŠΈλ₯Ό ν•©λ‹ˆλ‹€.

 

μœ„μ˜ refμ—μ„œ μ–ΈκΈ‰ν–ˆλ“―μ΄, 객체 전체λ₯Ό ꡐ체할 일이 μ—†λ‹€λ©΄ reactiveλ₯Ό μ‚¬μš©ν•˜λŠ”κ²Œ 더 μ ν•©ν•˜κΈ΄ ν•˜μ§€λ§Œ,

객체에도 refλ₯Ό μ‚¬μš©ν•˜λŠ” μ˜ˆμ‹œλ₯Ό λ³΄μ—¬λ“œλ¦¬λ©΄ λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

 

<template>
  <div>
    <p>Name: {{ user.name }}</p>
    <p>Age: {{ user.age }}</p>
    <button @click="updateName('Jane Doe')">Change Name</button>
  </div>
</template>
<script setup>
import { ref } from 'vue'
const user = ref({})
user.value = {
  name: 'John Doe',
  age: 30,
}

const updateName = (newName) => {
  user.value.name = newName
}
</script>

 

refλ₯Ό μ‚¬μš©ν•˜κ²Œλ˜λ©΄ .value둜 μ ‘κ·Όν•΄μ•Όν•˜λŠ”λ° 객체도 λ§ˆμ°¬κ°€μ§€μž…λ‹ˆλ‹€.

μœ„μ™€ 같이 ref둜 μ„ μ–Έν•œ κ°μ²΄λŠ” user.value둜 μ ‘κ·Όν•˜λ©°, name속성을 κ°€λ₯΄ν‚¬ λ•ŒλŠ” user.value.name으둜 λ“€μ–΄κ°€μ•Όν•©λ‹ˆλ‹€.