Vue 允許我們對 HTML Tag 使用 v-model
達成 Two-way Binding,我們也可使用 v-model
對 Prop 達成 Two-way Binding。
Version
macOS Catalina 10.15.6
Vue 2.6.11
v-model
5
為 outerCount
model,而 inner +
為 MyCounter
內的 button。
outerCount
會傳進 MyCounter
,且當 inner +
遞增時也會 two-way binding 更新 outerCount
。
App.vue
<template>
<div>
{{ outerCount }}
<MyCounter v-model="outerCount"></MyCounter>
</div>
</template>
<script>
import MyCounter from '@/components/MyCounter.vue'
export default {
data: () => ({
outerCount: 3
}),
components: {
MyCounter
}
}
</script>
12 行
data: () => ({
outerCount: 3
}),
定義 outerCount
model,且初始值為 3
。
第 2 行
<div>
{{ outerCount }}
<MyCounter v-model="outerCount"></MyCounter>
</div>
outerCount
除了以 v-model
傳入 <MyCounter>
外,也在外層顯示,因此我們希望 outerCount
能 two-way binding。
MyCounter.vue
<template>
<button @click="onClick">inner +</button>
</template>
<script>
let onClick = function() {
this.$emit('input', this.value +1)
}
export default {
props: [
'value'
],
methods: {
onClick
}
}
</script>
11 行
props: [
'value'
],
若要使用 v-model
,Vue 規定一定要使用 value
prop。
第 6 行
let onClick = function() {
this.$emit('input', this.value +1)
}
若要使用 v-model
,Vue 規定一定要發出 input
event。
v-model vs. .sync
v-model
與 .sync
都能達成 prop 的 two-way binding,但有以下差異:
- 一個 component 只能有一個
v-model
,但能有多個.sync
v-model
必須使用value
prop 與input
event;.sync
可自訂 prop 名稱,event 則為update:prop名稱
- 若只有一個 prop 需 two-way binding,建議使用
v-model
;若有多個 prop 需 two-way binding,則可第一個使用v-model
,其他使用.sync
,或者全部使用.sync
Conclusion
- Component 傳遞資料的關鍵在於 prop 與 event,
v-model
的 two-way binding 雖然看似神奇,但骨子裡還是離不開 prop 與 event,且一定要value
prop 與input
event