λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°
πŸ“  archive

Vue.js μ—μ„œ λ°˜μ‘ν˜•(Reactivity)을 λ‹€λ£¨λŠ” 방법

by HandHand 2021. 3. 2.

πŸ“Œ λ“€μ–΄κ°€λ©°

이번 ν¬μŠ€νŒ…μ—μ„œλŠ” Vue.js 의 λ°˜μ‘ν˜• μ‹œμŠ€ν…œμ— λŒ€ν•΄ μ•Œμ•„λ³΄κ³ μž ν•©λ‹ˆλ‹€.
졜근 μ§„ν–‰ν•˜κ³  μžˆλŠ” μ‚¬μ΄λ“œ ν”„λ‘œμ νŠΈμ—μ„œ μ»΄ν¬λ„ŒνŠΈμ˜ data 에 변경을 ν•΄μ€˜λ„

props 둜 μžμ‹μ—κ²Œ 전달해쀀 값이 κ°±μ‹ λ˜μ§€ μ•ŠλŠ” λ¬Έμ œκ°€ λ°œμƒν–ˆμŠ΅λ‹ˆλ‹€.
ν˜Ήμ‹œλ‚˜ ν•΄μ„œ μ°Ύμ•„λ³΄λ‹ˆ μ΄λŠ” reactivity λ₯Ό κ³ λ €ν•˜μ§€ μ•Šμ•„ λ°œμƒν•œ λ¬Έμ œμ˜€μŠ΅λ‹ˆλ‹€.

πŸ“Œ λ°˜μ‘ν˜•μ΄λž€?

Vue.js μ—μ„œλŠ” μ–΄λ–»κ²Œ μ»΄ν¬λ„ŒνŠΈ μΈμŠ€ν„΄μŠ€μ˜ data 속성 값을 μΆ”μ ν•˜μ—¬ 화면에 λžœλ”λ§μ„ 해쀄 수 μžˆλŠ” κ²ƒμΌκΉŒμš”?

μ΄λŠ” λ°”λ‘œ 각 μ»΄ν¬λ„ŒνŠΈ μΈμŠ€ν„΄μŠ€λ§ˆλ‹€ ν• λ‹Ήλœ watcher λ₯Ό 톡해 λ³€κ²½ 사항을 좔적 및 κ΄€λ¦¬ν•˜κΈ° λ•Œλ¬Έμ— κ°€λŠ₯ν•œ μΌμž…λ‹ˆλ‹€.

Vue.js λŠ” μΈμŠ€ν„΄μŠ€ μ΄ˆκΈ°ν™” λ‹¨κ³„μ—μ„œ data 의 λͺ¨λ“  속성에

getter / setter λ₯Ό μΆ”κ°€ν•˜μ—¬ 관리 및 갱신에 ν•„μš”ν•œ 연산을 μˆ˜ν–‰ν•©λ‹ˆλ‹€.

또 ν•œκ°€μ§€ μ€‘μš”ν•œ 사싀은 Vue.js λŠ” DOM μ—…λ°μ΄νŠΈλ₯Ό 비동기 둜 μˆ˜ν–‰ν•œλ‹€λŠ” κ²ƒμž…λ‹ˆλ‹€.
데이터 변경이 λ°œμƒν•˜μ—¬ DOM 을 μ—…λ°μ΄νŠΈ ν•΄μ•Όν•  경우 큐λ₯Ό μ—΄κ³  λͺ¨λ“  데이터 변경을 버퍼에 κΈ°λ‘ν•©λ‹ˆλ‹€.
이후 ν•΄λ‹Ή λ³€κ²½ 사항듀은 이벀트 루프 tick μ—μ„œ λŒ€κΈ°μ—΄μ„ λΉ„μš°κ³  μ‹€μ œ λ³€κ²½ μž‘μ—…μ„ μˆ˜ν–‰ν•©λ‹ˆλ‹€.

πŸ“Œ 리슀트 λ Œλ”λ§ μ‹œ μ£Όμ˜μ‚¬ν•­

Vue.js λŠ” 배열에 인덱슀둜 ν•­λͺ©μ„ 직접 μ„€μ •ν•˜λŠ” κ²½μš°λ‚˜ λ°°μ—΄ 길이λ₯Ό μˆ˜μ •ν•˜λŠ” κ²½μš°μ—λŠ”

λ³€κ²½ 사항을 좔적할 수 μ—†μŠ΅λ‹ˆλ‹€.

κ·Έλ ‡μ§€λ§Œ κ·Έ μ™Έ μ•„λž˜μ˜ 변이 λ©”μ†Œλ“œκ°™μ€ κ²½μš°λŠ” λž˜ν•‘λ˜μ–΄μžˆμ–΄ μƒνƒœ λ³€ν™” 유무λ₯Ό 좔적할 수 μžˆμŠ΅λ‹ˆλ‹€.

  • push(), pop()
  • shift(), unshift()
  • splice()
  • sort()
  • reverse()

πŸ“Œ μ΄λ²ˆμ— λ°œμƒν•œ 문제의 원인은 λ¬΄μ—‡μ΄μ—ˆμ„κΉŒ?

1️⃣ 리슀트 λ Œλ”λ§ 이슈

export default {
  data() {
    return {
      current: 0, // ν˜„μž¬ λ°°μ—΄ 인덱슀
      answer: [], // μ‚¬μš©μž μž…λ ₯ 값듀을 μ €μž₯ν•˜λŠ” λ°°μ—΄
      userInput: "", // μ‚¬μš©μž μž…λ ₯ κ°’
    };
  },

  methods: {
    handleNext() {
      // currnt(인덱슀) 증가, answer κ°€ μΆ”κ°€λœ 이후 싀행됨
    },

    saveData(data) {
      this.answer[this.current] = data;
      this.handleNext();
    },
  },
};

κ·Έλ ‡λ‹€λ©΄ κΈ°μ‘΄ μ½”λ“œλ₯Ό μ‚΄νŽ΄λ³΄λ©° 무엇이 λ¬Έμ œμ˜€λŠ”μ§€ νŒŒμ•…ν•΄λ³΄κ² μŠ΅λ‹ˆλ‹€.
κΈ°μ‘΄μ—λŠ” μ‚¬μš©μžκ°€ μž…λ ₯ν•œ 단어듀을 μ €μž₯ν•˜λŠ” λ°°μ—΄ answer κ°€ μœ„μ™€ 같이 data 에 μ„ μ–Έλ˜μ–΄ μžˆμŠ΅λ‹ˆλ‹€.

λ˜ν•œ μ‚¬μš©μžκ°€ 단어λ₯Ό μž…λ ₯ν•  경우 λ°œμƒν•˜λŠ” 이벀트 ν•Έλ“€λŸ¬μΈ saveData ν•¨μˆ˜μ˜ 경우

ν˜„μž¬ λ°°μ—΄μ˜ μΈλ±μŠ€κ°’μ— μžˆλŠ” 값을 μƒˆλ‘œμš΄ κ°’μœΌλ‘œ λŒ€μ²΄ν•˜λŠ” μž‘μ—…μ„ ν•˜κ³  있죠.

그런데 μœ„μ—μ„œ μ‚΄νŽ΄λ΄€λ“―μ΄ Vue.js λŠ” 인덱슀둜 직접적인 접근을 톡해 값을 λ³€κ²½ν•  경우

이 변경사항을 좔적할 수 μ—†κΈ° λ•Œλ¬Έμ— λ‹€μ‹œ λžœλ”λ§μ΄ λ°œμƒν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

λ”°λΌμ„œ μ•„λž˜μ™€ 같이 Vue μ—μ„œ μ œκ³΅ν•˜λŠ” set λ©”μ†Œλ“œλ‚˜ splice λ₯Ό ν™œμš©ν•˜μ—¬ 값을 λ³€κ²½ν•΄μ€λ‹ˆλ‹€.

  saveData(data) {
    this.$set(this.answer, this.current, data);
    this.handleNext();
  }

2️⃣ 비동기 μ—…λ°μ΄νŠΈ 이슈

아직 ν•œ 가지 문제점이 λ‚¨μ•„μžˆμŠ΅λ‹ˆλ‹€.
μœ„ μ½”λ“œλ₯Ό λ³΄μ‹œλ©΄ 데이터λ₯Ό κ°±μ‹ ν•˜κ³  인덱슀λ₯Ό μ¦κ°€μ‹œν‚€λŠ” handleNext ν•¨μˆ˜λ₯Ό μˆ˜ν–‰ν•˜λŠ” 것을 μ•Œ 수 μžˆμŠ΅λ‹ˆλ‹€.
ν•˜μ§€λ§Œ κ·ΈλŒ€λ‘œ μ‹€ν–‰μ‹œν‚¬ 경우 λ‹€μŒκ³Ό 같이 단어가 μž˜λ €μ„œ μž…λ ₯λ˜λŠ” λ¬Έμ œκ°€ λ°œμƒν•˜λŠ” 것을 확인할 수 μžˆμŠ΅λ‹ˆλ‹€.

단어가 μž˜λ €μ„œ μž…λ ₯되고 μžˆμŠ΅λ‹ˆλ‹€.. πŸ˜…

Vue.js μ—μ„œ DOM 이 λΉ„λ™κΈ°λ‘œ μ—…λ°μ΄νŠΈ 처리λ₯Ό ν•˜λŠ” 것이 μ›μΈμ΄μ—ˆμŠ΅λ‹ˆλ‹€.

화면에 μ—…λ°μ΄νŠΈκ°€ λ˜κΈ°λ„ 전에 μΈλ±μŠ€κ°€ μ¦κ°€ν•˜μ—¬ (handleNext) λ°œμƒν•œ ν˜„μƒμ΄μ—ˆμŠ΅λ‹ˆλ‹€.

 

λ”°λΌμ„œ λ‹€μŒκ³Ό 같이 데이터 변경을 마친 ν›„ DOM μ—…λ°μ΄νŠΈλ₯Ό 마칠 λ•ŒκΉŒμ§€ 기닀리기 μœ„ν•΄

Vue.nextTick(콜백) 을 μ‚¬μš©ν•˜λ„λ‘ λ³€κ²½ν•΄μ€¬μŠ΅λ‹ˆλ‹€.

saveData(data) {
  this.$set(this.answer, this.current, data);
  this.$nextTick(() => {
    this.handleNext();
  })
}

πŸ“Œ μ°Έκ³  자료

λ°˜μ‘ν˜•

πŸ’¬ λŒ“κΈ€