看了一整天,問chatgpt好多個蠢問題之後,甚至還跟它談心了,"v-model真的看不懂怎麼辦...?"
雙向綁定這樣的說法好像很炫,但我聽不太懂有點被搞混了,文件內提到一個字"synced with",同步,嗯..好像有點什麼了。
最基本的v-model似乎是從表單開始的,想同步的東西是表單裡某個元素的值和另一個ref(可以用來渲染到template裡),像是文件裡的一個簡單例子,在還沒有v-model之前的日子,需要用v-bind & v-on來實現:
我寫了input->text & input<-text這樣有沒有比較有雙向綁定
的感覺?
<script setup>
import { ref } from 'vue'
const text = ref('')
function onInput(e) {
text.value = e.target.value
}
</script>
<template>
<input :value="text" @input="onInput" placeholder="Type here">
<p>{{ text }}</p>
</template>
有了v-model的今天,所有的事情變得好簡單,這部份
<input
:value="text"
@input="event => text = event.target.value">
改寫成
<input v-model="text">
簡單到之前我看不懂也用地好開心 XD
組件的v-model是要同步誰呢?簡單說就是child.vue裡的一個ref & parent.vue的另一個ref。
拿一個文件內的例子來看一下,就是想做到child.vue的model要和parent.vue的msg同步。不過再看一眼child.vue裡的input元素裡居然還有另一個v-model,這是為了同步model & input欄位的值,於是model像是中間的橋樑,最後的結果是做出child.vue的input欄位值與parent.vue的msg同步。
<script setup>
const model = defineModel()
</script>
<template>
<span>My input</span> <input v-model="model">
</template>
<script setup>
import Child from './Child.vue'
import { ref } from 'vue'
const msg = ref('Hello World!')
</script>
<template>
<h1>{{ msg }}</h1>
<Child v-model="msg" />
</template>
這邊引進了一個新的寫法defineModel
,它其實回傳了一個ref,所以model就看成一個ref,而它實際上作了什麼事呢?
<script setup>
const props = defineProps(['modelValue'])
const emit = defineEmits(['update:modelValue'])
</script>
<template>
<input
:value="props.modelValue"
@input="emit('update:modelValue', $event.target.value)"
/>
</template>
而<Child v-model="msg" />
又作了什麼事?其實一樣,就是v-on & v-bind,只是現在bind的是child裡定義的prop,on的是child定義的emit。
好高興在這樣的夜,聽著Gummy B想通了這一切,雖然大部分的內容其實文件裡都有 XD