π‘ λ³Έ ν¬μ€νΈλ Vue 2.x λ₯Ό κΈ°μ€μΌλ‘ μμ±λμμ΅λλ€.
Vueμ λ°μν μμ€ν μ μ΄λ»κ² λμν κΉ?
μ΄μ ν¬μ€νΈμμ μ κ° μ¬μ΄λ νλ‘μ νΈλ₯Ό μ§ννλ©° μ€μ λ§μ£Όνλ μ΄μμ ν¨κ»
Vue
μ λ°μν μμ€ν
μ λν΄μ κ°λ¨νκ² μμλ΄€λ€λ©΄
μ΄λ² ν¬μ€νΈμμλ λ΄λΆ λμμ λν΄ μ’ λ κΉμ΄ μλ λ΄μ©λ€μ μμλ³΄λ €κ³ ν©λλ€.
π Vue λ μ΄λ»κ² μν λ³νλ₯Ό κ°μ§ν κΉ?
λ€μμ data
λ₯Ό νλ©΄μ 보μ¬μ£Όλ κ°λ¨ν Vue
μ»΄ν¬λνΈ μμμ
λλ€.
<template>
<div>
<h1 class="hello">
{{ name }}
</h1>
<input v-model="name" />
<div>
</template>
<script>
export default {
name: "HelloWorld",
data() {
return {
name: "HandHand",
};
},
};
</script>
μ¬κΈ°μ name
κ°μ΄ λ³κ²½λλ©΄ μ΄ κ°μ΄ νλ©΄μ κ·Έλλ‘ λ°μλ©λλ€.
Vue
λ΄λΆμ μΌλ‘λ μ΄ κ³Όμ μ΄ μ΄λ»κ² μ§νλλ κ²μΌκΉμ?
λ€μμ Vue
곡μ λ¬Έμμ μκ°λμ΄μλ λ°μνμ λμ μ리μ λν κ·Έλ¦Όμ
λλ€.
data μμ±μ ν λΉ λ°©μ
Vue
λ data
λ‘ JavaScript κ°μ²΄λ₯Ό ν λΉνκ² λλ©΄ Object.defineProperty
λ₯Ό νμ©ν΄μ
ν΄λΉ κ°μ²΄μ getter / setter
λ₯Ό μ μν©λλ€.
μ΄ λλΆμ λ°μ΄ν°μ λ³ν λ° μ°Έμ‘°λ₯Ό κ°μ§ν μ μλ κ²μ΄μ£ .
μ»΄ν¬λνΈ watcher ν λΉ
λͺ¨λ Vue μ»΄ν¬λνΈλ watcher
μΈμ€ν΄μ€λ₯Ό κ°μ§κ² λ©λλ€.
μ΄λ μ»΄ν¬λνΈκ° λ λλ§μ νμν λͺ¨λ μμ‘΄μ±μ μΆμ νλ μν μ λ΄λΉν©λλ€.
watcher
κ° λ λλ§μ μμ‘΄νκ³ μλ λ°μ΄ν°μ setter
κ° μ
λ°μ΄νΈλλ©΄ μ΄λ₯Ό κ°μ§νκ³
μ»΄ν¬λνΈμ 리λ λλ§μ λ°μμν€λ κ²μ λλ€.
μμλ₯Ό ν΅ν΄ μμλ΄ μλ€
λ°©κΈ μ€λͺ ν λ΄μ©μ μμ μμλ₯Ό ν΅ν΄ μ΄ν΄λ³΄κ² μ΅λλ€.
data
μΈname
μh1
κ³Όinput
μμμμ μ°Έμ‘°λκ³ μμ΅λλ€.Vue
κ° λ λλ§μ μνν λh1
κ³Όinput
μ μ°Έμ‘°λμ΄μλname
μ μ½μΌλ©΄μ (touch
)getter
κ° μνλκ³ μ΄ λμ μμ‘΄μ± μ 보λ₯Όwatcher
μκ² μ립λλ€.- μ΄ν λ°μ΄ν°κ° μμ λμμ λ
setter
κ° μνλλ©΄μ μ»΄ν¬λνΈκ° μμ‘΄νκ³ μλ
λ°μ΄ν° λ³νλ₯Όwatcher
κ° κ°μ§νλ©΄μ 리 λ λλ§μ μ§μν©λλ€.
π Vueλ λΉλκΈ°λ‘ DOMμ μ λ°μ΄νΈν©λλ€.
λΉλκΈ° DOM μ λ°μ΄νΈ Queue
μ΄μ ν¬μ€νΈμμ μΈκΈνλ―μ΄ Vue
λ λΉλκΈ°λ‘ DOM μ
λ°μ΄νΈλ₯Ό μ§νν©λλ€.
data
μ λ³νκ° κ°μ§λλ©΄ νλ₯Ό μμ±ν λ€ μ΄λ₯Ό push
ν©λλ€.
μ΄λ κ°μ μ΄λ²€νΈ 루νμμ λ°μλ λͺ¨λ λ°μ΄ν° λ³νλ₯Ό λ²νΌλ§ νμ¬
λμΌν watcher
κ° μ¬λ¬ λ² νΈμΆλλ κ²μ ν λ²μ νΈμΆλ‘ μ΅μ νν λ€ push
νκ² λ©λλ€.
μ΄ν λ€μ μ΄λ²€νΈ 루νκ° tick
λλ€λ©΄, Vue
λ queue
μμ μμ
μ κΊΌλ΄
νμν DOM μ λ°μ΄νΈλ₯Ό μνν©λλ€.
Vue.nextTick
Vue
λ μ§μ μ μΈ DOM μ κ·Όμ ν΅ν μ²λ¦¬λ₯Ό μ§μνκ³ data-driven
λ°©μμΌλ‘
λ‘μ§μ μΈμ°λ κ²μ κΆμ₯νκ³ μμ§λ§, κ°λ μ§μ DOMμ μ κ·Όν΄μ κ°μ κ°μ ΈμμΌ ν λκ° μμ΅λλ€.
μμ λ§νλ―μ΄ DOM μ λ°μ΄νΈλ μ΄λ²€νΈ 루νλ₯Ό ν΅ν΄ λΉλκΈ°μ μΌλ‘ μνλκΈ° λλ¬Έμ
λ§μ½ DOMμμ μλ‘ μ
λ°μ΄νΈλ κ°μ μ°Έμ‘°ν΄μΌ νλ€λ©΄ Vue.nextTick
μ ν΅ν΄μ
DOMμ΄ μ λ°μ΄νΈλ₯Ό μμ ν λ§μΉκΈ°λ₯Ό κΈ°λ€λ €μΌ ν©λλ€.
methods: {
async updateName() {
this.name = "JH";
console.log(this.$el.textContent); // HandHand
await this.$nextTick();
console.log(this.$el.textContent); // JH
},
}
π Vue λ΄λΆ ꡬν λ€μ¬λ€λ³΄κΈ°
μ΄λ²μλ μ€μ Vue
μ ꡬν μ½λμμ μ λ°©μμ΄ μ΄λ»κ² ꡬμ±λμ΄μλμ§ μ΄ν΄λ³΄κ² μ΅λλ€.
defineReactive
reactive
ν μμ±μ μ μνλ ν¨μμ
λλ€.
ν΄λΉ ν¨μ λ΄λΆ ꡬνμ 보μλ©΄ λ€μκ³Ό κ°μ΄ λμ΄μμ΅λλ€.
μ΄ν΄λλ₯Ό λμ΄κΈ° μν΄ μ€μν λΆλΆλ§ λͺ μνμ΅λλ€.
export function defineReactive(/** */) {
const dep = new Dep();
// ...
let childOb = !shallow && observe(val);
Object.defineProperty(obj, key, {
// ...
get: function reactiveGetter() {
// ...
dep.depend();
if (childOb) {
childOb.dep.depend();
if (Array.isArray(value)) {
dependArray(value);
}
}
// ...
},
set: function reactiveSetter(newVal) {
// ...
childOb = !shallow && observe(newVal);
dep.notify();
},
});
}
보μλ€μνΌ defineReactive
λ μΈμ€ν΄μ€ data
μ κ° ν€λ€μ λν΄ getter
μ setter
λ₯Ό μ€μ ν©λλ€.
1οΈβ£ getter
Dep
μ ν΄λΉ μμ±μ μμ‘΄μ±μΌλ‘ μΆκ°ν©λλ€.
μ΄λ λ°°μ΄μ κ²½μ° μ¬κ·μ μΌλ‘ μμ‘΄μ±μ μΆκ°νλ dependArray
λ₯Ό νΈμΆν©λλ€.
2οΈβ£ setter
μλ‘μ΄ κ°μ λν Observerλ₯Ό μμ±ν λ€ Dep
μ μμ‘΄νλ κ°μ λ³νκ° μκ²Όλ€λ κ²μ notify
ν©λλ€.
Observer (Dep & Watcher)
Observer
λ observable
ν κ°κ°μ κ°μ²΄μ ν λΉλ©λλ€.
μ΄λ₯Ό ν΅ν΄ μμ‘΄μ± λ³νλ₯Ό κ°μ§νκ³ μ λ°μ΄νΈλ₯Ό μνν©λλ€.
class Observer {
constructor(value: any) {
this.dep = new Dep();
def(value, "__ob__", this);
if (Array.isArray(value)) {
this.observeArray(value);
} else {
this.walk(value);
}
}
walk(obj: Object) {
/**
* defineReactive λ₯Ό ν΅ν΄ κ°μ²΄μ λͺ¨λ μμ±μ λ°μνμΌλ‘ λ§λλλ€.
*/
}
observeArray(items: Array<any>) {
/**
* λ°°μ΄μ κ° μμμ observer λ₯Ό ν λΉν©λλ€.
*/
}
}
Observer
λ κ°μ²΄ λ΄λΆμ __ob__
μμ±μ ν λΉν©λλ€.
λν λ°°μ΄μ λν μ’
μμ± κ²μ¬λ₯Ό μν΄ μ¬κ·μ μΌλ‘ Observer
λ₯Ό μμ±νλ©°
κ·Έ μΈ κ°μ²΄μ κ²½μ° κ° μμ±λ€μ defineReactive
λ₯Ό ν΅ν΄ λ°μνμΌλ‘ λ§λλλ€.
βοΈ Dep
class Dep {
static target: ?Watcher;
id: number;
subs: Array<Watcher>;
constructor() {
this.subs = [];
}
addSub(sub: Watcher) {
this.subs.push(sub);
}
removeSub(sub: Watcher) {
remove(this.subs, sub);
}
depend() {
if (Dep.target) {
Dep.target.addDep(this);
}
}
notify() {
const subs = this.subs.slice();
for (let i = 0, l = subs.length; i < l; i++) {
subs[i].update();
}
}
}
Dep
μ λ΄λΆμ μΌλ‘ Watcher
λ°°μ΄μ μ μ§ν©λλ€.
ꡬλ
- λ°ν λͺ¨λΈλ‘ μμ‘΄μ±μ λ³νλ₯Ό notify
λ°κ² λλ©΄ update
λ₯Ό ν΅ν΄ Watcher
μκ² μ립λλ€.
βοΈ Watcher
class Watcher {
// ...
update() {
if (this.lazy) {
this.dirty = true;
} else if (this.sync) {
this.run();
} else {
queueWatcher(this);
}
}
}
π μ°Έκ³ μλ£
'π archive' μΉ΄ν κ³ λ¦¬μ λ€λ₯Έ κΈ
JWT (JSON Web Token) (0) | 2022.05.23 |
---|---|
Cookie & Web Storage (0) | 2022.05.22 |
[Vue.js μνκ΄λ¦¬ 3νΈ] Vuex μΈμ , μ΄λ»κ² μ¨μΌν κΉ? (0) | 2022.03.07 |
[Vue.js μνκ΄λ¦¬ 2νΈ] Vuex λ₯Ό μ΄μ©ν μν κ΄λ¦¬ (0) | 2022.03.07 |
[Vue.js μνκ΄λ¦¬ 1νΈ] Vue.Observable μ ν΅ν μνκ΄λ¦¬ (0) | 2022.03.07 |
π¬ λκΈ