Vue自定義組件實現v-model指令


Tips: 本文所描述的Vue均默認是Vue2版本

在我們初次接觸Vue的時候,一定會了解到一個語法糖,那就是v-model指令,它帶給我們的第一印象就是它可以實現雙向綁定

那么,什么是雙向綁定?通俗一點來說,就是當數據發生變化的時候,視圖同時發生變化,這可以說是Vue的精髓之處了
(不過關於雙向綁定,后續可以出一篇更為詳盡的博文來深入模擬一下Vue的實現,這里重點還是探討實現自定義組件的v-model指令)

所以,在我們深入使用Vue之后,編寫一個自定義組件,如何手動實現一個v-model的指令呢,今天我們就來詳細探討一下

v-model指令的原理是什么?

  1. v-bind綁定一個value屬性
  2. v-on監聽當前元素的input事件,當數據變化時,將值傳遞給value實時更新數據

v-modelv-bind:value有什么區別?

自定義組件中,必定會使用v-bind指令來實現組件之間值的傳遞,所以在我還是菜鳥的那段時間,我一直有個疑惑,
既然有的v-bind指令,為什么還需要在自定義的組件中實現v-model指令呢?在我實踐了一番之后,我才明白,
v-model既能夠實現值的傳遞,也能夠實現頁面數據的實時變化,而v-bind只是實現值的傳遞,如果需要實現實時變化的效果,
需要使用另外的方法修改變量的值,可以總結為下面兩點

  1. v-model實現視圖和數據的雙向綁定,一者變化另一者也會同時變化
  2. 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~ 😃
轉發請注明參考文章地址,非常感謝!!!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM