v-model原理
先看一個(gè)例子
<el-input v-model='value' />
這是我們?cè)陂_發(fā)中常用的輸入框的雙向綁定晾捏,他實(shí)際的原理是
<el-input v-bind:value="value" v-on:input="value=$event.target.value">
v-model的原理就是v-bind數(shù)據(jù)綁定與v-on處理函數(shù)綁定的語(yǔ)法糖。
日常開發(fā)中會(huì)遇到很多種需要對(duì)組件進(jìn)行封裝或者已有組件的二次封裝工作穿撮,而且不限于表單組件缺脉,在vue中2.2后新增了model
語(yǔ)法,可以更好的實(shí)現(xiàn)業(yè)務(wù)組件的封裝悦穿。
model官網(wǎng)解釋
允許一個(gè)自定義組件在使用 v-model 時(shí)定制 prop 和 event攻礼。默認(rèn)情況下,一個(gè)組件上的 v-model 會(huì)把 value 用作 prop 且把 input 用作 event栗柒,但是一些輸入類型比如單選框和復(fù)選框按鈕可能想使用 value prop 來(lái)達(dá)到不同的目的礁扮。使用 model 選項(xiàng)可以回避這些情況產(chǎn)生的沖突。
用法
假如我們有一個(gè)需求瞬沦,需要對(duì)已有ui組件庫(kù)中的input做一下二次封裝,所有項(xiàng)目中使用到的輸入框都要限制字?jǐn)?shù)0-100太伊,原有組件是支持這個(gè)功能的,但是對(duì)于項(xiàng)目中大量使用的input來(lái)說(shuō)逛钻,在每一個(gè)input上添加maxlength以及minlength會(huì)特別麻煩僚焦。
我們以element-ui的el-input組件來(lái)做一個(gè)簡(jiǎn)單的例子, 組件代碼如下
<template>
<div>
<el-input :value='currentValue' @change='onChange' :maxlength='100' :minlength='0' />
</div>
</template>
<script>
export default {
name: 'myInput',
data() {
return {
currentValue: this.value
}
},
model: {
prop: 'value',
event: 'change'
},
props: {
value: {
type: String
}
},
watch: {
value: {
handler() {
this.currentValue = value
}
}
},
methods: {
onChange(val) {
this.$emit('change', val)
}
}
}
</script>
上述組件代碼中,我們使用model屬性來(lái)指定prop以及event,當(dāng)我們?cè)诟附M件中使用的時(shí)候,只需要綁定v-model屬性曙痘。
<template>
<my-input v-model='myInputValue' />
</template>
這樣一個(gè)數(shù)據(jù)雙向綁定的組件就封裝完成了芳悲。
注意
內(nèi)部定義
currentValue
的意義在于保證單向數(shù)據(jù)流立肘,輸入框本身的值是由父組件傳入的value決定的,不能由子組件內(nèi)部改變芭概,當(dāng)發(fā)生change事件后赛不,由子組件emit一個(gè)事件觸發(fā)父組件值的變化,再由子組件中的watch監(jiān)聽value變化重新給currentValue賦值this.$emit('change', val)
中的事件名稱必須和model: {prop: 'value',event:'change'},
中的event名稱一致model的屬性不只限于表單組件罢洲,任何形式的組件都可以使用這個(gè)特性踢故,來(lái)實(shí)現(xiàn)v-model