在 Vue 中,v-model 是一個常用的指令,它能夠?qū)崿F(xiàn)表單元素的雙向綁定。在輸入框中輸入內(nèi)容時,自動同步到對應(yīng)的數(shù)據(jù)屬性中;反之,修改數(shù)據(jù)屬性時,輸入框內(nèi)容也會跟著更新。一個常見的示例代碼如下:
<template> <div> <input v-model="message"> <p>{{ message }}</p> </div> </template> <script> export default { data() { return { message: '', } }, } </script>
上面的代碼中,我們首先在 data 選項中定義了一個空字符串 message。然后在模板中使用 v-model 指令綁定了一個輸入框和 message。在頁面中輸入內(nèi)容時,數(shù)據(jù)屬性 message 會隨之更新,同時在頁面中顯示的內(nèi)容也會即時變化。
在 Vue 實現(xiàn) v-model 的過程中,實際上做了一些常規(guī)的數(shù)據(jù)雙向綁定處理。在輸入框中輸入內(nèi)容時,通過監(jiān)聽 input 事件更新數(shù)據(jù),代碼如下:
// 獲取輸入框元素 const input = document.querySelector('input') // 監(jiān)聽 input 事件 input.addEventListener('input', function (event) { // 更新數(shù)據(jù) this.message = event.target.value })
而當(dāng)數(shù)據(jù)屬性值發(fā)生變化時,頁面中的輸入框內(nèi)容也需要作出相應(yīng)的改變。Vue 內(nèi)部通過給輸入框的 value 屬性賦值實現(xiàn)這個效果,代碼如下:
// 監(jiān)聽數(shù)據(jù) message 的變化 watch: { message(newVal) { // 獲取輸入框元素 const input = document.querySelector('input') // 給輸入框賦值 input.value = newVal }, }
除了以上的處理,Vue 的實現(xiàn)中還考慮了一些細節(jié)問題。例如,在組件上使用 v-model 時,要通過 props 和 emit 對數(shù)據(jù)進行傳遞和觸發(fā)事件,具體的實現(xiàn)方式如下:
// 在定義組件時,聲明 props 可以接受一個 modelValue 屬性 props: { modelValue: { type: String, default: '' }, }, // 在模板中,使用 v-bind 將父組件傳遞的 modelValue 綁定到組件的 value 上 <template> <input v-bind:value="modelValue" v-on:input="$emit('update:modelValue', $event.target.value)"> </template> // 在 Vue 實例中,使用 v-model 綁定組件上的 modelValue <template> <div> <CustomInput v-model="message"> <p>{{ message }}</p> </div> </template>
通過以上的實現(xiàn),我們就可以在組件內(nèi)部使用 v-model 了。同時,我們也了解了 v-model 的底層實現(xiàn)原理,以及一些細節(jié)問題,將幫助我們更好地理解 Vue 的工作方式。