Tips: 本文所描述的Vue均默認是Vue2版本
在我們初次接觸Vue
的時候,一定會了解到一個語法糖,那就是v-model
指令,它帶給我們的第一印象就是它可以實現雙向綁定
那么,什么是雙向綁定?通俗一點來說,就是當數據發生變化的時候,視圖同時發生變化,這可以說是Vue
的精髓之處了
(不過關於雙向綁定,后續可以出一篇更為詳盡的博文來深入模擬一下Vue的實現,這里重點還是探討實現自定義組件的v-model指令)
所以,在我們深入使用Vue
之后,編寫一個自定義組件,如何手動實現一個v-model
的指令呢,今天我們就來詳細探討一下
v-model
指令的原理是什么?
v-bind
綁定一個value
屬性v-on
監聽當前元素的input
事件,當數據變化時,將值傳遞給value
實時更新數據
v-model
和v-bind:value
有什么區別?
自定義組件中,必定會使用v-bind
指令來實現組件之間值的傳遞,所以在我還是菜鳥的那段時間,我一直有個疑惑,
既然有的v-bind
指令,為什么還需要在自定義的組件中實現v-model
指令呢?在我實踐了一番之后,我才明白,
v-model
既能夠實現值的傳遞,也能夠實現頁面數據的實時變化,而v-bind
只是實現值的傳遞,如果需要實現實時變化的效果,
需要使用另外的方法修改變量的值,可以總結為下面兩點
v-model
實現視圖和數據的雙向綁定,一者變化另一者也會同時變化v-bind
只會在初始化的時候將數據綁定到視圖上,后續視圖變化不會影響數據
擼一個v-model
看到這里,相信你也理解了為什么我們會需要在自定義的組件中自定義一個v-model指令,下面我們通過一個簡易的示例來擼一個v-model
,
在此之前我們需要在一個空Vue
項目中,定義一個dad.vue文件,以及child.vue文件。
為了方便初學者學習,我將一個完整的簡易示例項目放到了github倉庫中供大家下載學習,
大家如果喜歡可以為了點一顆Star,Thanks♪(・ω・)ノ!!!
dad.vue
<template>
<div>
<child v-model='childName'></child>
</div>
</template>
<script>
import child from './child.vue';
export default {
name: 'dad',
components: {
child
},
data() {
return {
childName: '我是兒子'
};
},
methods: {}
};
</script>
child.vue
<template>
<!-- vue中的自定義組件中,若父組件中用v-model的話,其實相當於v-bind:value='***'並且v-on:input='***' -->
<!-- 因此子組件內部用props接收value值,用$emit觸發input事件,默認傳遞value值和input事件是模擬v-model的默認規則 -->
<!-- 基礎知識提示:@是v-on監聽事件的簡寫,:是v-bind綁定屬性的簡寫 -->
<div class="box-v-model">
<input type="text" class="input-v-model" :value="value" @input="inputChange" />
<!-- 簡寫的方式 -->
<!-- <input type="text" @input="value=$event.target.value" :value="value" /> -->
<div>{{ value }}</div>
</div>
</template>
<script>
export default {
name: "child",
props: {
value: {
type: String
}
},
methods: {
// $emit 方法可以觸發當前實例上的事件,這里觸發的事input事件,附加參數都會傳給監聽器回調
// input 事件在用戶輸入時觸發,它是在元素值發生變化時立即觸發
inputChange(e) {
this.$emit("input", e.target.value);
}
}
}
</script>
參考文檔一 ———— vue自定義組件中的v-model
參考文檔二 ———— Vue中v-model和v-bind:value的區別以及手動實現v-model
參考文檔三 ———— Vue官方文檔關於$emit的說明
我是 fx67ll.com,如果您發現本文有什么錯誤,歡迎在評論區討論指正,感謝您的閱讀!
如果您喜歡這篇文章,歡迎訪問我的 本文github倉庫地址,為我點一顆Star,Thanks~ 😃
轉發請注明參考文章地址,非常感謝!!!