Clones Vue.js to implement a basic MVVM framework
β νκ΅μ΄ | English
νλμ μΈ νλ μμν¬λ€μ΄ MVVM(Model-View-ViewModel)
ν¨ν΄μ μ¬μ©νμ¬ ν¨μ¨μ μΈ λ°μ΄ν° λ°μΈλ©κ³Ό μ¬μ©μ μΈν°νμ΄μ€ κ΄λ¦¬λ₯Ό μ§μνλ€λ μ μμ μκ°μ λ°μ μ΄λ¬ν MVVM
ν¨ν΄μ κΈ°λ°μΌλ‘ Vue.js
λ₯Ό ν΄λ‘ νμ¬ μ μ¬ν κΈ°λ₯κ³Ό λ¬Έλ²μ μ 곡νλ κΈ°μ΄μ μΈ MVVM
νλ μμν¬μ
λλ€.
μ΄ μ μ₯μμ μ£Όλ λͺ©νλ Vue.js
μ ν΅μ¬ λμ λ°©μμ ν΄λ‘ νλ©΄μ, MVVM
ν¨ν΄κ³Ό ν΅μ¬μ μΈ μ΅μ λ² ν¨ν΄μ μ μ©ν΄ 보λ κ²μ
λλ€. νλ‘μ νΈμ μ λ°μ μΈ κ΅¬μ‘°λ #Referenceμ μ½λλ₯Ό κΈ°λ°μΌλ‘ νμμΌλ©° 볡μ‘ν λ¬Έμ λ₯Ό κ³ λ €νμ§ μμμ§λ§, μλ°©ν₯ λ°μ΄ν° λ°μΈλ©κ³Ό Vue.js
μ ν΅μ¬μ리λ₯Ό μ΄ν΄νλλ° λμμ μ€ μ μλ€κ³ μκ°ν©λλ€.
vuelite
λ₯Ό npm
μμ μ€μΉνκ³ νλ‘μ νΈμμ μ¬μ©νλ €λ©΄, λ€μ λͺ
λ Ήμ΄λ₯Ό μ€ννμΈμ
npm install vue-lite-js@latest
λΈλΌμ°μ μμ μ§μ μ¬μ©νλ €λ©΄, μλμ κ°μ΄ cdn
μ ν΅ν΄ μ€ν¬λ¦½νΈλ₯Ό ν¬ν¨νμΈμ
<script src="https://unpkg.com/vue-lite-js@latest"></script>
κ°λ° νκ²½μμ μμ€ μ½λλ₯Ό μμ νκ³ μ§μ ν μ€νΈ νκ³ μΆμΌλ©΄, λ€μ λ¨κ³λ₯Ό λ°λΌμ£ΌμΈμ
git clone https://github.com/Heonys/vue-lite-js
npm install
npm run start
π¦ vuelite
βββ π dev
β βββ π index.html β
β βββ π index.ts β
βββ π src β
β βββ π core
β βββ π types
β ...
src
ν΄λ μμ μμ€μ½λλ₯Ό μμ νκ³ dev
ν΄λμμ λ§ν¬λ€μ΄κ³Ό μ€ν¬λ¦½νΈ μμ±μ΄ κ°λ₯ν©λλ€.
CDN Demo:
https://vuelite-demo.vercel.app
<div id="app">
<input type="text" v-model="message" />
<p v-style="textStyle">{{ message }}</p>
<button v-on:click="handleClick">change vuelite</button>
<div>
<input type="checkbox" v-model="checked" />
<span>{{ isChecked }}</span>
</div>
</div>
import Vuelite from "vue-lite-js";
new Vuelite({
el: "#app",
data() {
return {
message : "",
checked: true,
textStyle: { color: "#FF0000" },
}
},
methods: {
handleClick() {
this.message = "vuelite";
},
},
computed: {
isChecked() {
return this.checked ? "checked" : "unchecked";
},
}
})
-
κΈ°λ³Έμ μΌλ‘
Vue.js
μ Option API λ°©μμ ν΄λ‘ νκ³ μμΌλ©°,Vue.js
μ ν΅μ¬ κΈ°λ₯μ μ§μνμ§λ§ λͺ¨λ κΈ°λ₯μ μ§μνμ§ μμ΅λλ€. -
μ΅μ μμ
template
μμ±μ μ§μνμ§λ§,Vue.js
μ.vue
νμ₯μμ κ°μ λ‘λλ₯Ό μ§μνμ§ μκΈ° λλ¬ΈμHTML
νμΌμμ λ°λ‘ λ§ν¬μ μ μμ±ν΄μΌ νλ λΆνΈν¨μ΄ μμ΅λλ€. λ°λΌμ ν νλ¦Ώμ λΆλ¦¬ν΄μ μ¬μ©νλ λ°©μμ μ ν΅μ μΈVue.js
보λ€λAngular
μ μ μ¬ν λ©΄μ΄ μμ΅λλ€. -
μ±κΈ νμΌ μ»΄ν¬λνΈ ν¬λ§·μ μ§μνμ§ μλ μ΄λ¬ν νΉμ± λλ¬Έμ
<style>
νκ·Έ ννλ₯Ό μ§μνκΈ° μν΄μstyles
μμ±μ μ§μν©λλ€.
new Vuelite({
// ...
styles: {
"#wrapper": {
// only camelCase key
width: "50%",
background: "#ffa",
cursor: "pointer",
},
},
})
v-if/else
μv-show
λ₯Ό ν΅ν μ‘°κ±΄λΆ λ λλ§μ μ§μνμ§λ§,<template>
μμμv-if
λ₯Ό μ§μνμ§ μμμ λ¨μΌ μ리먼νΈμμλ§ μ¬μ©κ°λ₯νλ©°v-else-if
λλ ν°λΈλ₯Ό μ§μνμ§ μμ΅λλ€.
class Vuelite {
constructor(options: Options) {
this.el = document.querySelector(options.el);
this.options = options;
injectReactive(this);
injectStyleSheet(this);
const scanner = new VueScanner(new NodeVisitor());
scanner.scan(this);
}
}
MVVM
ν¨ν΄μμ viewmodel
μν μ μννλ vue
μΈμ€ν΄μ€μ μμ± λ¨κ³λ‘ option
κ°μ²΄λ₯Ό λ°μμ DOM
κ³Ό λ°μ΄ν° λ°μΈλ©μ μ 곡ν μ μλλ‘ νλ μ§μ
μ μν μ ν©λλ€.
Viewmodelμ ꡬννλ ν΅μ¬ μμ΄λμ΄
- μ΅μ κ°μ²΄λ‘ λ°μμ¨ λ°μ΄ν°μ λ°μμ±μ λΆμ΄λ£μ΄ λ°μ΄ν°μ λ³νλ₯Ό κ°μ§
- DOMμ μννλ©° λλ ν°λΈλ₯Ό νμ±νκ³ μ΅μ λ²λ₯Ό μμ±
- λ°μν λ°μ΄ν°μ μ΅μ λ²μ μνΈμμ©μ λ°λ₯Έ μλ°©ν₯ λ°μΈλ©μ λ¬μ±
// target: λννλ €λ μλ³Έ κ°μ²΄
// handler: λμμ κ°λ‘μ±λ λ©μλμΈ 'νΈλ©(trap)'μ΄ λ΄κΈ΄ κ°μ²΄
new Proxy(target, handler);
Proxy κ°μ²΄λ μλ³Έ κ°μ²΄λ₯Ό κ°μΈλ κ°μ²΄λ‘ νκ²μ΄ λλ μλ³Έ κ°μ²΄μ λν μ κ·Όμ μ μ΄νκ±°λ, νΉμ λμμ κ°λ‘μ±μ μλ‘μ΄ κΈ°λ₯μ μΆκ°ν μ μκ² νλ λν κ°μ²΄μ λλ€.
viewmodel
μμ λ°μ΄ν°μ λ³νλ₯Ό κ°μ§νμ¬ μ€μ λ·°(DOM)μμ μλ°©ν₯ λ°μΈλ©νλ κ²μ΄ μ°λ¦¬μ λͺ©μ μ΄κΈ° λλ¬Έμ λ°μ΄ν°μ λ³νμ μ΄λ»κ² κ°μ§ν μ μμμ§ κ³ λ―Όν΄ λ΄μΌ νλλ° μ΄λ₯Ό μν΄ μλ°μ€ν¬λ¦½νΈμμλ μΈμ΄ μ°¨μμμ κ°μ²΄μ μμ±μ λμ μΌλ‘ getter
μ setter
λ₯Ό λ±λ‘ν μ μκ² ν΄μ£Όλ Object.defineProperty
μ λλΆμ΄ Proxy
λ₯Ό μ¬μ©νμ¬ μ΄λ₯Ό ꡬνν μ μμ΅λλ€.
μ€μ λ‘
Vue2
μμλdefineProperty
λ‘ λ°μν λ°μ΄ν°λ₯Ό ꡬννκ³ ,Vue3
μμλProxy
λ₯Ό μ¬μ©νμ¬ λ°μν λ°μ΄ν°λ₯Ό ꡬνν©λλ€.
λ°λΌμ Proxy
κ°μ²΄λ‘ viewmodel
μ λͺ¨λ data
μμ±μ λννμ¬ get νΈλ©
, set νΈλ©
μ μΆκ°νκ³ λͺ¨λ μμ±λ€μ λ³νλ₯Ό κ°μ§νλλ‘ κ΅¬νν κ²μ
λλ€.
const handler = {
get(target: Target, key: string, receiver: Target) {
// 1. get νΈλ© (getter)
},
set(target: Target, key: string, value: any, receiver: Target) {
// 2. set νΈλ© (setter)
},
};
new Proxy(data, handler);
νμ§λ§ Proxy
λ₯Ό μμ±νλ νμ¬ λ¨κ³μμ getter
, setter
λ₯Ό μ€λͺ
νκΈ° λν΄ν λΆλΆμ΄ μ‘΄μ¬νλλ° ν·κ°λ¦¬μ§ λ§μμΌ νλ건 μ΄ λΆλΆμ ν΄λΉ μμ±μ μ κ·Όνκ±°λ ν΄λΉ μμ±μ κ°μ μμ ν λ μλνλ νΈλ©μΌλ‘ μ΄μ°¨νΌ λμ€μ μ€νλλ λΆλΆμΌλ‘ ν΅μ¬μ μΈ λ‘μ§μ΄κΈ΄ νμ§λ§, μ§κΈ λ¨κ³μμ κ·Έλ₯ getter
, setter
λ₯Ό λ±λ‘ν¨μΌλ‘μ¨ Reactivty
λ₯Ό μ£Όμ
νꡬλ νκ³ μκ°νλ©΄ λ κ² κ°μ΅λλ€.
-
get νΈλ©
Dep κ°μ²΄λ₯Ό μμ±νκ³ νμ¬ νμ±νλ Observerμμ μμ‘΄μ±μ μ°κ²°νλ μν μ ν©λλ€.Scanner
μμ λλ ν°λΈλ₯Ό νμ±νκ³Observer
λ₯Ό μμ±ν λ, ν΄λΉ λλ ν°λΈμ ν΄λΉνλexpresion
μvm
μμ μ°Ύλ κ³Όμ μμgetter
λ₯Ό λ°μμν€κ³ λ°λΌμ ν΄λΉexpresion
μ 맀νλλDep
μ΄ μμ±λμ΄ μμ±λObserber
μμ μ°κ²°μ΄ λ§Ίμ΄μ§λλ€. -
set νΈλ©
get νΈλ©
μ μ΅μ λ²κ° μμ±λ λ μ΄λ―Έ νλ²μ μ€νλμκΈ° λλ¬Έμ μ΄νμset νΈλ©
μμλ νμ ν΄λΉνλkey
μ λμνλDep
κ³Ό 맀νλμ΄ μμ΅λλ€.setter
κ° λ°μν μμ μ ν΄λΉ μμ± κ°μ λ³νκ° μΌμ΄λ¬λ€λ λ»μΌλ‘notify
λ₯Ό νΈμΆν¨μΌλ‘μ¨ ν΄λΉDep
μ ꡬλ νκ³ μλ λͺ¨λObserver
λ€μκ² λκ° μμ‘΄νκ³ μλ μμ±μ λ³νκ° μΌμ΄λ¬μΌλupdate
λ₯Ό νλΌκ³ μλ¦Όμ 보λ΄λ μν μ ν©λλ€.
Dep
κ°μ²΄λ Dependency
μ μ½μλ‘ λ°μ΄ν°μ λ³νλ₯Ό κ°μ§νκ³ , ꡬλ
μμΈ Observer
λ€μκ² μλ¦Όμ νλ μν μ ν©λλ€. Proxy
λ₯Ό μμ±ν λ λ°μ΄ν°μ λͺ¨λ μμ±λ§λ€ Dep
κ°μ²΄κ° μμ±λλ κ²μΌλ‘λ μ μ μμ§λ§ λͺ¨λ λ°μν λ°μ΄ν°λ€μ 맀νλλ Dep
μ κ°μ§κ³ μμ΅λλ€. μ¬κΈ°μ Dep
μΈμ€ν΄μ€ μ체λ 맀νλ λ°μν λ°μ΄ν°μ λν μνλ₯Ό κ°μ§κ³ μμ§ μμΌλ©°, μ΄λ Reactivty
μ define
λ©μλμμ λ΄λΆμ μΌλ‘ deps
λΌλ μ΄λ¦μΌλ‘ key
μ Dep
λ₯Ό 맀ννμ¬ κ΄λ¦¬νκ³ μκΈ° λλ¬Έμ λμ€μ setter
κ° λμν λ ν΄λ‘μ 곡κ°μ μλ deps
μ μ κ·Όνμ¬ λ§€νλλ key
κ° λμ§ μ μ μκΈ° λλ¬Έμ Dep
μ체λ μκΈ°κ° λ§€νλ ν€μ λν μνλ₯Ό κ°κ³ μμ§ μκ³ notify
λ₯Ό ν μ μμ΅λλ€.
class Dep {
static activated: Observer
//...
}
activated
μμ±μ νμ¬ νμ±νλ μ΅μ λ²κ° 무μμΈμ§ μνλ₯Ό κ°κ³ Dep
κ³Ό Obserber
μ μμ‘΄κ΄κ³λ₯Ό λ§ΊκΈ° μν static
λ³μλ‘ μΌμ’
μ μ μλ³μ κ°μ λλμΌλ‘ μ¬μ©λ©λλ€.
injectMethod(vm);
injectComputed(vm);
DOM
κ³Ό λ°μΈλ©μ΄ λμ΄μΌ νλ data
λ€κ³Όλ λ€λ₯΄κ² computed
μ method
λ€μ λ°μμ±μ μ£Όμ
ν νμκ° μμ΅λλ€. λ°λΌμ viewmodel
μμ μ κ·Όν μ μλλ‘ viewmodel
μ μμ±μΌλ‘ λ±λ‘ν΄ μ£Όλ©΄ λλλ° ν΅μ¬μ this
λ°μΈλ©μ ν΅ν΄ computed
λλ method
λ΄λΆμμ this
λ₯Ό μ¬μ©ν λ this
κ° vm
μ κ°λ¦¬ν€λλ‘ λͺ
μμ μΌλ‘ μ§μ ν΄ μ€λλ€.
const scanner = new VueScanner(new NodeVisitor());
scanner.scan(this);
μ΅μ
μμ μ λ¬λ°μ el
μμ±μΌλ‘λΆν° νμμ λͺ¨λ λ
Έλλ₯Ό μννλ©΄μ v-
μ λμ¬κ° λΆμ λλ ν°λΈ μμ± λλ ν
νλ¦Ώ λ¬Έλ² {{ }}
μ μ¬μ©νκ³ μλ λͺ¨λ ν
μ€νΈλ₯Ό κ²μ¬ν©λλ€. μ¬κΈ°μ DOM
μ μννλκ² μλ Node
λ¨μλ‘ μννλ μ΄μ λ ν
νλ¦Ώμ νμ±νκΈ° μν΄ ν
μ€νΈ λ
ΈλκΉμ§ κ²μ¬ν΄μΌνκΈ° λλ¬Έμ
λλ€.
λ
Έλ μνλ₯Ό μν΄ μννλ μν μ체λ Visitor
μκ² μμνκ³ λ
Έλλ§λ€ μ²λ¦¬ν ꡬ체μ μΈ μ‘μ
μ Scanner
μμ μ²λ¦¬νλλ‘ Visitor
μ Scanner
λ₯Ό λΆλ¦¬ν©λλ€.
const action = (node: Node) => {
isReactiveNode(node) && new Observable(vm, node);
};
λͺ¨λ λ
Έλλ₯Ό μννλ©΄μ ν΄λΉ λ
Έλκ° λλ ν°λΈλ₯Ό κ°κ±°λ ν
μ€νΈμ ν
νλ¦Ώ λ¬Έλ²μ κ°μ‘λμ§λ₯Ό νμΈνκ³ Observable
μμ±ν©λλ€.
μ¬κΈ°μ Observable
μ λ¨μν v-
μ λμ¬λ₯Ό κ°λ λλ ν°λΈμΈμ§ ν
νλ¦ΏμΈμ§μ μ¬λΆλ§ νμΈνμ¬ Directive
λ₯Ό μμ±νκ³ , ν
νλ¦Ώ λ°μΈλ©μ v-text
λλ ν°λΈλ‘ λ³κ²½λ©λλ€. μ΄λ, μ΄λ²€νΈλ₯Ό λ±λ‘νλ v-on
μ μ μΈνκ³ λͺ¨λ λλ ν°λΈλ λλ ν°λΈ μ’
λ₯μ λ°λΌμ updater
λ₯Ό μΈμλ‘ λ°μμ v-bind
μμ μΌκ΄μ μΌλ‘ Observer
λ₯Ό μμ±ν©λλ€.
Vue.js
μ v-model
λλ ν°λΈλ μλ°©ν₯ λ°μ΄ν° λ°μΈλ©μ μμ£Ό κ°λ¨νκ² κ΅¬νν μ μκ²νλ λλ ν°λΈλ‘ μ¬μ©μ μ
λ ₯μ vue
μΈμ€ν΄μ€μ λ°μ΄ν°μ μλμΌλ‘ λκΈ°νν©λλ€. λ°λΌμ μ¬μ©μμ μ
λ ₯μ λ°λ UI μμλ€μΈ input, textarea, select
μμμμ μ¬μ©λ©λλ€.
<!-- v-modelμ μ¬μ©ν μλ°©ν₯ λ°μΈλ© -->
<div>
<input type="text" v-model="title">
<div>{{ title }}</div>
</div>`;
<!-- λ¨λ°©ν₯ λ°μΈλ© + μ΄λ²€νΈ νΈλ€λ¬ -->
<div>
<input
type="text"
v-bind:value="title"
v-on:input="handleInput"
>
<div>{{ title }}</div>
</div>
μ€μ λ‘ v-model
μ μμ μ½λμ²λΌ v-bind
μ v-on:event
μ μ‘°ν©μΌλ‘ λμΌνκ² λμνλ©° vuelite
μμλ μ΄λ¬ν λκ°μ§ λ°©μμ λͺ¨λ μ§μν©λλ€.
<input type="checkbox" v-model="isChecked">
<input type="radio" name="gender" value="male" v-model="selectedOption">
<input type="radio" name="gender" value="female" v-model="selectedOption">
<select v-model="selectedRadio">
<option value="javascript">javascript</option>
<option value="python">python</option>
</select>
v-model
μ ꡬνν λ λ¬Έμ λ κ°κ°μ μμλ§λ€ λ°μΈλ©λλ κ°μ΄ value
, checked
λ±μΌλ‘ λ€λ₯Ό λΏλλ¬ κ°μ checked
μμ±μ λ°μΈλ© νλλΌλ checkbox
μ radio
λ²νΌμ λμ λ°©μμ΄ λ€λ₯΄κ³ , μ΄λ²€νΈλ change
, input
μ²λΌ λ¬λΌμ§κΈ° λλ¬Έμ μμμ κ°μ΄λ μνλ₯Ό ν΅μΌλ λ°©μμΌλ‘ μ κ·Όν μ μκ²ν΄μ μΌκ΄λκ² λ°μΈλ©νκ² ν΄μ€ νμκ° μμ΅λλ€.
λ°λΌμ Directive
ν΄λμ€μμ v-model
μ μ²λ¦¬ν λλ μ΄λ¬ν μμλ€ λλ νμ
μ λ°λΌμ μΌκ΄λκ² μ¬μ©ν μ μκ² λΆκΈ°μ²λ¦¬νμ¬ updater
μ μ΄λ²€νΈλ¦¬μ€λλ₯Ό λ±λ‘ν©λλ€.
bind(updater?: Updater) {
// ...
const value = evaluateValue(this.vm, this.exp);
updater && updater(this.node, value);
new Observer(this.vm, this.exp, (value) => {
updater && updater(this.node, value);
});
λλ ν°λΈ μ’
λ₯μ λ°λΌμ updater
κ° μ ν΄μ§κ³ κ²°κ³Όμ μΌλ‘ Obserber
κ° μμ±λ©λλ€.
μ¬κΈ°μ updater
λ Reactive
κ° μ£Όμ
λ μμ±μμ λ³νκ° μΌμ΄λ set νΈλ©
μμ notify
κ° λ°μνμ λ ν΄λΉ dep
μ ꡬλ
νκ³ μλ λͺ¨λ Observer
λ€μκ² λ³νκ° μΌμ΄λ¬μμ μλ¦¬κ³ μ
λ°μ΄νΈλ₯Ό μμ²νλ ꡬ체μ μΈ μ
λ°μ΄νΈ ν¨μλ₯Ό μλ―Έν©λλ€. μ¦, Observer
λ λ³νμ λμνμ¬ DOM
μ μ
λ°μ΄νΈνκ³ λ°λΌμ viewmodel
μ data
λ³νκ° μ΅μ’
μ μΌλ‘ νλ©΄μ λ°μλ©λλ€.
μμ μ½λμμ Observer
λ₯Ό μμ±νκΈ° μ μ updater
λ₯Ό 미리 νλ² μ€ννλλ° μ΄κ±΄ 첫 λ λλ§μ viewmodel
μ μμ±μ DOM
μ λ°μνκΈ° μν¨μ
λλ€.
μλ‘κ° μλ‘λ₯Ό 컬λ μ
μΌλ‘ κ΄λ¦¬νλ λ€λλ€μ κ΄κ³λ₯Ό κ°μ΅λλ€.
Dep
μ μ
μ₯μμλ μ¬λ¬ κ°μ λλ ν°λΈμμ κ°μ μμ±μ μ¬μ©ν μ μκΈ° λλ¬Έμ μ¬λ¬ Observer
λ€μ κ΄λ¦¬νλ κ²μ΄κ³ , λ°λλ‘ νλμ λλ ν°λΈμμ μ¬λ¬ κ°μ λ°μν λ°μ΄ν°μ μμ‘΄ν μ μκΈ° λλ¬Έμ Observer
λ μ¬λ¬ Dep
μ κ°μ§ μ μμ΅λλ€.
μ΅μ μμ μ λ¬ν data λ€μ λͺ¨λ 1:1λ‘ λ§€νλλ Depκ° μμ±λκ³ , λ°λλ‘ λͺ¨λ λλ ν°λΈλ 1:1λ‘ λ§€νλλ Observerκ° μμ±λμ΄ κ·Έ λμ΄ μνΈμμ© νλ€κ³ μκ°νλ©΄ λ©λλ€.
// Observer
getterTrigger() {
Dep.activated = this;
const value = evaluateValue(this.vm, this.exp);
Dep.activated = null;
return value;
}
// Dep
depend() {
Dep.activated?.addDep(this);
}
Observer
ν΄λμ€μλ getterTrigger
λ©μλκ° μ‘΄μ¬νλλ° μ΄ λ©μλμ μν μ λ¨μν vm
μμ ν΄λΉ μμ±μ κ°μ Έμ€λ μΌμ νκ³ μμ΄ λ³΄μ΄μ§λ§, μ΄ ν¨μλ κ·Έ μ΄μμΌλ‘ μ€μν μν μ νκ³ μμ΅λλ€.
- μ²μμ
Reactivty
ν΄λμ€μμ λͺ¨λdata
μμ±μ λνν νλ‘μ κ°μ²΄μget νΈλ©
μ μλμ μΌλ‘ λ°μμν€ μν΄ μ¬μ©λ©λλ€.get νΈλ©
μ΄ λ°μλκΈ° μ΄μ μDep.activated
λ₯Ό νμ¬μthis
μ¦, νμ¬μObserver
λ‘ μ€μ μ ν΄λκ³get νΈλ©
μ΄ λ°μνλ©΄dep.depend()
λ₯Ό νΈμΆνμ¬ νμ¬ νμ±νλObserver
μDep
μ κ΄κ³λ₯Ό ꡬμΆν©λλ€.
κ²°κ³Όμ μΌλ‘ getterTrigger
λ λ°μν λ°μ΄ν°μ get νΈλ©
μ λ°μμμΌμ Dep
κ°μ²΄λ₯Ό μμ±νλ©°, κ°μ κ°μ Έμ΄κ³Ό λμμ μ΄λ κ² λ§λ€μ΄μ§ Dep
κ°μ²΄κ° Observer
μμ κ΄κ³λ₯Ό λ§Ίμ΄μ£Όλ μ€μν μν μ ν©λλ€. μ¦, Obserber
λ Dep
μ ꡬλ
νμ¬ κΈ°λ€λ¦¬κ³ Dep
μ Obserber
μκ² κ°μλΉνλ€κ° Dep
μ΄ μμ μ λ³νκ° λ°μνμ λ ꡬλ
μ(Observer)λ€μκ² λ³νλ₯Ό ν΅μ§νλ κ΄κ³λ₯Ό νμ±ν©λλ€.
<div>
<input type="checkbox" v-model="visible" />
<span>{{ visible ? "π" : "π" }}</span>
<h1 v-if="visible">Vue is awesome!</h1>
<h1 v-else>Oh no π’</h1>
</div>
new Vuelite({
el: "#app",
data() {
return {
visible: true,
}
},
})
-
v-showμ v-ifμ μ°¨μ΄
v-show
λλ ν°λΈλ μμμ κ°μμ±μ μ μ΄νκΈ° λλ¬Έμ λ¨μν κ°μ λ°λΌμdisplay: none
μ μ¬λΆλ₯Ό κ²°μ ν΄ μ£Όλ©΄ λμ§λ§,v-if
λ 맀νλ λ°μ΄ν°κ°false
μΌ λDOM
μμ μ¬λΌμ§κ³true
κ° λ λ λ€μDOM
μ μ½μ λ©λλ€. μ¦,v-show
λ νμ λ λλ§λκ³ κ°μ λ°λΌμ μ€νμΌλ§ λ³κ²½ν΄ μ£Όλ©΄ λκΈ° λλ¬Έμ κΈ°μ‘΄μ λλ ν°λΈ μ²λΌ μ²λ¦¬ν μ μκ³ μμ£Ό λ¨μν λ°λ©΄,v-if
λ 쑰건λΆλ‘ μμκ° μμ λκ±°λ μ½μ λμΌνλλ° μ¬κΈ°μ μμ νλ 건 μ΄λ ΅μ§ μμ§λ§, λ€μ μ½μ λ λ μ΄λ»κ² μ΄μ μ μμΉλ₯Ό κΈ°μ΅νκ³ μλ μ리μ μ½μ ν μ§ κ³ λ―Όν΄ λ΄μΌν©λλ€. -
v-ifμ λμ νλ¦
v-if
λλ ν°λΈκ° μ μ©λ μμ λΆλͺ¨ μμμchildren
μμ±μ ν΅ν΄ νμ¬ μμμ΄ λͺ λ²μ§Έ μΈλ±μ€ μΈμ§λ₯Ό κΈ°μ΅- 쑰건μ΄
false
μΌλ νμ¬ λ λλ§λλv-if
μμ±μ κ°μ§ μμλ₯Όfragment
λ‘ μ΄λνμ¬ μμ보κ΄- μ‘°κ±΄μ΄ λ€μ
true
λλ©΄ λΆλͺ¨λ‘ λΆν° μκΉ κ΅¬ν μΈλ±μ€ μμΉ λ°λ‘ μ΄μ μfragment
λ‘ λΆν° λ€μ κ°μ κ°μ Έμμ μ½μv-else
λλ ν°λΈκ° μ‘΄μ¬νλ©΄v-if
μ μμ μ΄λ£¨κ³ μ΄μ λ°λλ‘ λμν¨
-
v-ifμ λ λλ§ μ λ΅
v-if
μ κ²½μ°λDOM
μ μ§μ μ μΈ μν₯μ λ―ΈμΉκΈ° λλ¬Έμ μ€κ°μDOM
μ ꡬ쑰λ₯Ό λ³κ²½νκ³ μ΄λ‘ μΈν΄ λ€λ₯Έ λλ ν°λΈκ° μ λΆ νμ±λκΈ° μ μ λ€λ₯Έ λλ ν°λΈμ μν₯μ λ―ΈμΉ μ μμμ΅λλ€. κ·Έλμv-if
λλ ν°λΈ μ²λ¦¬λ₯Ό λ―Έλ€λκ³ λͺ¨λ λλ ν°λΈλ₯Ό μ²λ¦¬ν νμlazy
νκ² μ²λ¦¬νλλ‘ νμμ΅λλ€. λνv-if
λ κΈ°μ‘΄μDirective
,Observer
μ κ΄κ³κ° μλCondition
μ΄λΌλ μΈμ€ν΄μ€λ₯Ό μλ‘ μμ±ν©λλ€. μλνλ©΄ 맀νλ κ°μ΄falsy
μΌλDOM
μ 보κ΄ν΄μΌνλ©°v-else
ꡬ문μ λν μμ μ΄λ€μΌνκΈ° λλ¬Έμ λ€λ₯Έ λλ ν°λΈμ λ€λ₯΄κ² μΆκ°μ μΈ μνλ₯Ό νμλ‘ ν΄μ λΆλ¦¬νμ΅λλ€. -
μ νμ¬ν
v-else-if
μ<template v-if>
λ μ§μνμ§ μμΌλ©°,v-else
λ λ°λμv-if
λ°λ‘ λ€μ μμ μμ μ΄λ£° λλ§ μ μ λμν©λλ€. κ·Έ μΈμ κ²½μ°μv-else
λλ ν°λΈκ° 무μλ©λλ€.
<ul>
<li v-for="item in items" :key="item.id">
{{ item.message }}
</li>
</ul>
data() {
return {
items: [
{ id: 1, message: "Item 1" },
{ id: 2, message: "Item 2" },
{ id: 3, message: "Item 3" },
{ id: 4, message: "Item 4" },
],
}
},
-
컨ν μ€νΈμ μμ±
-
μ νμ¬ν
:key μ 곡 x
-
methods, computed λ΄λΆμμ thisμ νμ μΆλ‘ λ° μλμμ± κ°μ<1.1.0>
-
λλ ν°λΈ μΆμ½ νν μ§μνκΈ°<1.2.1>
-
ν νλ¦Ώ λ¬Έλ²μμ ννμ μ§μνκΈ°<1.3.0>
-
μ‘°κ±΄λΆ λ λλ§ μΆκ° (v-if/else, v-show λλ ν°λΈ)<1.4.3>
-
리μ€νΈ λ λλ§ μΆκ° (v-for λλ ν°λΈ)<1.5.1>
- created, mounted, updated λ±μ λΌμ΄νμ¬μ΄ν΄ ν μ§μνκΈ°
- watch μ§μνκΈ°
- λΆλΆμ μΌλ‘ Composition API μ§μνκΈ°