iT邦幫忙

0

v-model

Pam 2024-04-19 01:13:39429 瀏覽
  • 分享至 

  • xImage
  •  

看了一整天,問chatgpt好多個蠢問題之後,甚至還跟它談心了,"v-model真的看不懂怎麼辦...?"
雙向綁定這樣的說法好像很炫,但我聽不太懂有點被搞混了,文件內提到一個字"synced with",同步,嗯..好像有點什麼了。

單一vue檔裡的v-model

最基本的v-model似乎是從表單開始的,想同步的東西是表單裡某個元素的值和另一個ref(可以用來渲染到template裡),像是文件裡的一個簡單例子,在還沒有v-model之前的日子,需要用v-bind & v-on來實現:

  • v-on用來把input的輸入值同步給text ref(也就是input->text):當有人在這個欄位輸入東西的時候(聽input這個event),執行onInput這個callback,作什麼呢?把text ref等於發生這個event的元素的值。
  • v-bind用來把text ref的值回到input的值(也就是input<-text),若有人在script裡對text作某些操控(改值之類的),input欄位也可以馬上響應這個變化。

我寫了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

組件的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同步。

  • child.vue
<script setup>
const model = defineModel()
</script>

<template>
  <span>My input</span> <input v-model="model">
</template>
  • parent.vue
<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,而它實際上作了什麼事呢?

  1. 定義了一個名為modelValue的prop: 作為child的一個客製屬性,可從parent那邊接資料回child來進行input value的同步
  2. 定義了一個名為update:modelValue的emit: 從child發出emit(with input value),去同步parent的msg
<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


圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言