vue中的attribute和property的具體使用及區(qū)別
作為 attribute 和 property 的 value 及 Vue.js 的相關(guān)處理
attribute 和 property 是 Web 開(kāi)發(fā)中,比較容易混淆的概念,而對(duì)于 value,因其特殊性,更易困惑,本文嘗試做一下梳理和例證
attribute 和 property 的概念
簡(jiǎn)單的說(shuō),attribute 是元素標(biāo)簽的屬性,property 是元素對(duì)象的屬性,例如:
<input id="input" value="test value">
<script>
let input = document.getElementById('input');
console.log(input.getAttribute('value')); // test value
console.log(input.value); // test value
</script>
- input 的 value attribute 是通過(guò)標(biāo)簽里的 value=“test value” 定義的,可以通過(guò)input.getAttribute(‘value') 獲取,可以通過(guò) input.setAttribute(‘value', ‘New Value') 更新
- input 的 value property 可通過(guò) input.value 獲取和更新,初始值是與 attribute 中的賦值一致的
attribute 和 property 的綁定
如果在最開(kāi)始的時(shí)候,更新 attribute value 的值,property 的值也會(huì)隨之改變
但是更新 property value 的值(在文本框輸入或給 input.value 賦新值 ),attribute 的值不會(huì)隨之改變,而且此時(shí)再更新 attribute 的值,property 的值也不再隨之改變,如此動(dòng)畫(huà)所示,也可訪問(wèn)此頁(yè)面嘗試進(jìn)行操作
這其實(shí)是臟值標(biāo)記(dirty value flag)在起作用,dirty value flag 的初始值為 false,即 attribute value 的更新默認(rèn)會(huì)改變對(duì)應(yīng)的 property value,但是一旦用戶交互修改了 property value,dirty value flag 的值就變?yōu)?true,即attribute value 的更新就不會(huì)改變對(duì)應(yīng)的 property value 了
所以在實(shí)際項(xiàng)目中,我們一般都是在處理作為 property 的 value
Vue.js 對(duì) value 的處理
一般情況使用 :value
Vue.js 的 v-bind,一般情況下是在處理 attribute,如果要作為 property 處理的話,需要加上 .prop
不過(guò) v-bind:value 卻大都默認(rèn)為處理 property 值,因?yàn)楸粡?qiáng)制轉(zhuǎn)化了,例如:
<input id="input" :value="'test value'" >
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
let input = new Vue({
el: '#input',
mounted () {
console.log(this.$el.getAttribute('value')); // null
console.log(this.$el.value); // test value
console.log(this._vnode.data) // {attrs: {id: "input"}, domProps: {value: "test value"}}
}
});
</script>
可見(jiàn),Vue.js 將 value 作為 VNode 的 data 中的 domProps 的屬性,而不是 attrs 的屬性,所以掛載后會(huì)成為作為 property 的 value
在 Vue.js 源碼中,強(qiáng)制轉(zhuǎn)化 property 的處理如下:
// src/compiler/parser/index.js
function processAttrs (el) {
...
if ((modifiers && modifiers.prop) || (
!el.component && platformMustUseProp(el.tag, el.attrsMap.type, name)
)) {
addProp(el, name, value, list[i], isDynamic)
} else {
addAttr(el, name, value, list[i], isDynamic)
}
其中 platformMustUseProp 在 web 平臺(tái)的定義如下:
// src/platforms/web/util/attrs.js
const acceptValue = makeMap('input,textarea,option,select,progress')
export const mustUseProp = (tag: string, type: ?string, attr: string): boolean => {
return (
(attr === 'value' && acceptValue(tag)) && type !== 'button' ||
(attr === 'selected' && tag === 'option') ||
(attr === 'checked' && tag === 'input') ||
(attr === 'muted' && tag === 'video')
)
}
由上可知,類(lèi)型不為 button 的 input, textarea, option, select, progress 的 value 會(huì)強(qiáng)制作為 property,而不需要設(shè)置為 :value.prop
例如 textarea 標(biāo)簽,其本身其實(shí)并不支持 value attribute,所以以下代碼中的 value 的值并不會(huì)顯示在多行文本框中
<textarea value="test value"></textarea>
但是在 Vue.js 中, 以下代碼能成功綁定到 value property 并顯示在多行文本框中
<textarea :value="'test value'"></textarea>
特殊情況使用 :value.prop
以上 Vue.js 源碼需要注意的還有,強(qiáng)制作為 property, 還要滿足 !el.component,即不為動(dòng)態(tài)組件,因?yàn)閯?dòng)態(tài)組件的 el.component 的值為其 is attribute 的值
即動(dòng)態(tài)組件的的 v-bind 默認(rèn)都是作為 attribute的,如果要作為 property,就要使用 .prop,例如:
<div id="app">
<component :is="element" :value.prop="'test value'"></component>
<button @click="change">Change</button>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
let app = new Vue({
el: '#app',
data: {
element: 'input'
},
methods: {
change () {
this.element = 'input' === this.element ? 'textarea' : 'input';
}
}
});
</script>
如果以上 component 中,刪除 :value.prop 的 .prop,切換到 textarea 時(shí),其值就不會(huì)顯示在多行文本框中,可以在此頁(yè)面點(diǎn)擊切換標(biāo)簽查看
總結(jié)
- 作為 attribute 和 property 的 value 的綁定關(guān)系會(huì)在用戶交互更新值后失效
- Vue.js 一般使用 :value 即可讓 value 作為 property
- Vue.js 動(dòng)態(tài)模版需要使用 :value.prop 才可讓 value 作為 property
到此這篇關(guān)于vue中的attribute和property的具體使用及區(qū)別的文章就介紹到這了,更多相關(guān)vue attribute property內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue3網(wǎng)絡(luò)請(qǐng)求添加loading過(guò)程
這篇文章主要介紹了vue3網(wǎng)絡(luò)請(qǐng)求添加loading過(guò)程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-08-08
Vite圖片資源打包優(yōu)化的實(shí)現(xiàn)
本文主要介紹了Vite圖片資源打包優(yōu)化的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-04-04
el-table表頭使用el-dropdown出現(xiàn)兩個(gè)下拉框的問(wèn)題及解決方法
本文給大家分享el-table在固定右邊列時(shí),表頭使用el-dropdown會(huì)出現(xiàn)兩個(gè)下拉框的解決方法,感興趣的朋友跟隨小編一起看看吧2024-07-07
VUE配置proxy代理的開(kāi)發(fā)測(cè)試及生產(chǎn)環(huán)境
這篇文章主要為大家介紹了VUE配置proxy代理的開(kāi)發(fā)環(huán)境、測(cè)試環(huán)境、生產(chǎn)環(huán)境詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-08-08
vue使用recorder.js實(shí)現(xiàn)錄音功能
這篇文章主要為大家詳細(xì)介紹了vue使用recorder.js實(shí)現(xiàn)錄音功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-11-11
vue 解決addRoutes多次添加路由重復(fù)的操作
這篇文章主要介紹了vue 解決addRoutes多次添加路由重復(fù)的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-08-08

