vue原生input輸入框原理剖析
正文
首先我們來看一段代碼:
<input value="value">
這里是一個原生的input輸入框,每一個原生的輸入框都會有一個value的屬性來用于存儲用于輸入的最新的數(shù)據(jù)。
如果我們想要獲取到這個值我們可以通過input.target.value或者通過$event.target.value來獲取這個存儲的值。
只要用戶輸入了數(shù)據(jù),那么此時input標(biāo)簽就會將輸入的數(shù)據(jù)放到這個value中(新數(shù)據(jù)會覆蓋舊數(shù)據(jù),所以我們獲取到的都是最新的)。
現(xiàn)在我們來看上面的標(biāo)簽,我們?yōu)?code>input標(biāo)簽添加了一個value屬性,并且賦值'value'。其實在標(biāo)簽上設(shè)置value屬性它的作用有兩個:
- 在第一次創(chuàng)建
input標(biāo)簽的時候,將對應(yīng)的初始值展示到輸入框中 (在無該屬性使輸入框不展示任何數(shù)據(jù)) - 使用
value屬性的初始值來初始化input.target.value(無該屬性時input.target.value為空串)
上面的那段代碼的意思是通過添加value="value"屬性,初始化input.target.value的值并且將初始值展示到對應(yīng)的輸入框中
這里需要注明一點,在后續(xù)用戶輸入的操作中,輸入框中的數(shù)據(jù)只是方便讓用戶看到自己輸入了什么僅此而已。 有人可以會有疑問,難道不是input.target.value里是什么所以輸入框內(nèi)就顯示什么嗎?其實不是的。
輸入框顯示什么和 input.target.value并沒有直接聯(lián)系,輸入框內(nèi)的顯示只是方便用戶自己看到自己輸入了什么。
小結(jié):
input中的value有兩種:value="xxx" 和 input.target.value 我們需要知道兩個分別有什么作用。在整個輸入顯示流程中, 他們分別扮演什么角色。
現(xiàn)在我們來看在vue中的輸入框,首先我們來看一段代碼:
<input
v-bind:value
@input="value = $event.target.value"
/>
data(){
return {
value:'123'
}
}
我們一般使用v-bind:value來給Input標(biāo)簽綁定一個vue中的的,這里我們綁定的是this.value。 在這里v-bind:value === :value="value"。 這樣實現(xiàn)的原理比較簡單。
首先我們定義了this.value因為將this.value綁定到了:value上,所以初始時會在輸入框展示我們指定的 值,即'123'。當(dāng)我們輸入數(shù)據(jù)之后,此時$envet.target.value(這里的$event.target.value就是input.target.value)就會存儲我們最新的輸入的值,然后將最新的值賦值給this.value。
因為this.value變化了,此時vue對頁面進行更新,此時更新后的input的:value是最新值。
但是這里有一個問題,那就是<input>并不會被銷毀重建,也就是說this.value = $event.target.value只是改變了this.value 若別的地方引用了this.value,那么就會同步改變。那么this.value的更新對:value="value"的影響是什么呢?其實沒有什么影響。
因為我們前面說了,:value的作用有兩個:一是初始化input.value的值,二是將初始值渲染到對應(yīng)的輸入框中。 在一開始將this.value作為初始值給Input.value和展示在框里,他的任務(wù)已經(jīng)完成了,后續(xù)的更改對:value沒有一點關(guān)系。
其實:value="value"的唯一作用就是將this.value作為初始值綁定和展示到input上。
v-model
現(xiàn)在對于原始元素進行算雙向數(shù)據(jù)綁定已經(jīng)完成。那么如何實現(xiàn)父組件和子組件之間的雙向數(shù)據(jù)綁定嗯? 此時我們需要在子組件中使用v-model。 關(guān)于 v-model 的使用這里不再贅述。這里只討論如何在自定義組件實現(xiàn) v-model。根據(jù)vue 的官網(wǎng)的描述,我們大概知道,v-model 的本質(zhì)就是語法糖,即:
<input type="text" v-model="name"> 相當(dāng)于: <input type="text" :value="name" @input="name = $event.target.value">
vue監(jiān)聽輸入框輸入行為然后改變對應(yīng)的值。 如果對子組件進行雙向數(shù)據(jù)綁定該如何實現(xiàn)呢?這里的雙向數(shù)據(jù)綁定指的是父組件將值傳遞給子組件使用,并且子組件可以改變父組件的值 其實上述的雙向綁定可以通過v-bind:propName.sync = 'xxx'來實現(xiàn)。 除了以上的方式,并且Vue還給我們提供了另一種方式:
<!-- 父組件.vue -->
<child-component :propName="data" @change="change" />
export default {
data(){
data:'123'
},
methods:{
change(value){
this.data = value
}
}
}
//在組件中如何想要改變父組件的值,那么直接出發(fā)對應(yīng)的事件即可:
this.$emit('change', newValue )
在vue中,它將上述的方法進行了簡化,我們可以使用v-model來對子組件進行雙向數(shù)據(jù)綁定。例如:
<child-component v-model="pageTitle" /> <!-- 是以下的簡寫: --> <child-component :value="pageTitle" @input="pageTitle = $event" />
在默認(rèn)情況下v-model的觸發(fā)事件名稱為input。 子組件想要使用的話,需要定義一個名為value的prop才能使用。 而在子組件中更改該值,只需要定義一個函數(shù),有必要的時候執(zhí)行 this.$emit('input', newValue) 即可。
這里的newValue就是$event。 這樣就可以改變對應(yīng)的值。 當(dāng)然除了默認(rèn)的value和input的命名,vue還給我們提過了更加靈活的方式。
<!-- 父組件 --> <child-component v-model="pageTitle" />
//子組件
export default {
model: {
prop: 'title', //這里相當(dāng)于別名,這里可以起其他名稱
event: 'change' //這里相當(dāng)于事件的別名,這里可以起其他名稱
},
props: {
// 這將允許 `value` 屬性用于其他用途
value: String,
// 使用 `title` 代替 `value` 作為 model 的 prop
title: {
type: String,
default: 'Default title'
}
}
}
當(dāng)我們想在子組件中改變傳入的值,那么直接可以this.$emit('change', newValue)
所以,在這個例子中 v-model 是以下的簡寫:
<child-component :title="pageTitle" @change="pageTitle = $event" />
其實本質(zhì)上,項目中的twowayFactor這個混入配置類,他本質(zhì)上就是做了上面的操作。
@Prop()
@Model('valueChanged')
bindValue!: T;
這樣做的目的是將v-model傳入的prop改為bindValue。 然后將默認(rèn)事件的名稱從input改為了valueChange。 接著設(shè)置get/set
get currentValue() {
return this.bindValue;
}
set currentValue(value) {
this.$emit('valueChanged', value);
}
這樣做的目的是數(shù)據(jù)本地化。 在組件內(nèi)部定義一個currentValue 然后為該值設(shè)置get,當(dāng)訪問currentValue等價于訪問v-model的prop。 然后設(shè)置set。當(dāng)改變currentValue的值時,此時就會觸發(fā)對應(yīng)的事件。 當(dāng)觸發(fā)之后父組件中的值就會變化。這就實現(xiàn)了雙向數(shù)據(jù)綁定。
我們可以看到,其實this.currentValue的作用就是v-model操作的語法糖。 它并沒有什么特別之處,只是將v-model傳入的數(shù)據(jù)的訪問和更改簡單化了,都集中與一個值this.currentValue。
以上就是vue原生input輸入框原理剖析的詳細(xì)內(nèi)容,更多關(guān)于vue原生input輸入框的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
ant design Vue 純前端實現(xiàn)分頁問題
這篇文章主要介紹了ant design Vue 純前端實現(xiàn)分頁問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-04-04
Vue報錯"Failed?to?resolve?loader:less-loader"的解決方
這篇文章主要給大家介紹了關(guān)于Vue報錯"Failed?to?resolve?loader:less-loader"的解決方法,文中通過圖文介紹的非常詳細(xì),對同樣遇到這樣問題的朋友具有一定的需要的朋友可以參考下2023-02-02
Vue3?封裝?Element?Plus?Menu?無限級菜單組件功能的詳細(xì)代碼
本文分別使用?SFC(模板方式)和?tsx?方式對?Element?Plus?*el-menu*?組件進行二次封裝,實現(xiàn)配置化的菜單,有了配置化的菜單,后續(xù)便可以根據(jù)路由動態(tài)渲染菜單,對Vue3?無限級菜單組件相關(guān)知識感興趣的朋友一起看看吧2022-09-09
element表格el-table實現(xiàn)虛擬滾動解決卡頓問題
當(dāng)頁面數(shù)據(jù)過多,前端渲染大量的DOM時,會造成頁面卡死問題,本文主要介紹了element表格el-table實現(xiàn)虛擬滾動解決卡頓問題,具有一定的參考價值,感興趣的可以了解一下2023-10-10

