現(xiàn)在vue框架用起來雖然很方便坯台,很爽炬丸,但是難免也會遇到一些問題,其中新手遇到的data屬性更改了但卻沒有刷新界面蜒蕾,即不響應(yīng)的問題是比較煩人的稠炬,下面我就介紹一下,為vue新手的起步之路掃除一個(gè)障礙??咪啡。
給vue實(shí)例添加屬性一般有兩種方式首启。
-
直接寫在data里面
data() {
return {
name:''
}
}
-
data中沒有age屬性
vm.age = 26
對于這兩種情況,第一種的name
是響應(yīng)的撤摸,而第二種的age
無法響應(yīng)毅桃。為什么呢,我們再解釋下是否響應(yīng)是怎么來的准夷,即vue給屬性添加響應(yīng)關(guān)系的過程是怎樣的钥飞。
vue會在vue實(shí)例初始化的時(shí)候?qū)?code>data中的屬性執(zhí)行
getter/setter
轉(zhuǎn)化過程,所以屬性必須在data
對象上存在才能讓 Vue 轉(zhuǎn)換它衫嵌。
很明顯读宙,第二種的age
錯(cuò)過了添加getter/setter
轉(zhuǎn)化的時(shí)機(jī),所以無法響應(yīng)渐扮。
不過我相信大多數(shù)人遇到問題的都不是這種,而是第一例的另一種情況,我直接上部分代碼:
data() {
return {
person:{}
}
},
methods:{
btnPressed():{
this.person.name = '張三'
}
}
這種情況的話掖棉,person
的name
確實(shí)是被改成了'張三'
墓律,相信你也log
了好幾次,但是為什么界面上就是沒有更改呢幔亥,原因剛才已經(jīng)說過了耻讽,因?yàn)檫@里的name
并未添加getter/setter
的監(jiān)測方法,即無法響應(yīng)帕棉,當(dāng)這個(gè)name
的值改變的時(shí)候针肥,界面上無法進(jìn)行相應(yīng)的更改,那有些人可能會說我這個(gè)person
不是響應(yīng)的嗎香伴?
沒錯(cuò)慰枕,person
是響應(yīng)的,但這里的person
是個(gè)對象即纲,對person
添加getter/setter
轉(zhuǎn)化方法時(shí)具帮,person
還沒有name
這個(gè)字段,所以person
可以響應(yīng),而person.name
無法響應(yīng)蜂厅。
推測
data
中的對象類型的屬性匪凡,如果在data
中已寫出,就會被添加getter/setter
方法進(jìn)行響應(yīng)式監(jiān)測處理掘猿,而沒有寫的則不會病游,查了很多資料,好像也確實(shí)是這個(gè)道理稠通,如以下這個(gè)例子衬衬。
<template>
<div id="app">
<div>{{person.name}}</div>
<div>{{person.age}}</div>
<button @click="btnPressed">點(diǎn)擊</button>
</div>
</template>
<script>
export default {
name: 'app',
data(){
return {
person:{name:''}
}
},
created(){
this.person.name = 'liu'
this.person.age = '100'
},
methods:{
btnPressed(){
this.person.name = 'zhao'
this.person.age = '200'
}
}
}
</script>
根據(jù)推測,界面上應(yīng)該一開始出現(xiàn)'liu'
和'100'
兩行采记,但是點(diǎn)擊了按鈕執(zhí)行btnPressed
之后佣耐,第一行會變?yōu)?code>'zhao',而第二行不變唧龄,還是'100'
兼砖。
但是!既棺!結(jié)果兩個(gè)值都變了讽挟,第二行也變?yōu)榱?code>'200',之后我又加了各種屬性丸冕,gender
,father
等耽梅,依然都跟著改變,只要person
中有其中一個(gè)初始值胖烛,它的所有屬性就都會變成響應(yīng)式眼姐;
然而,將person
的屬性key
由'name'改為'names'佩番,那么這里的name
和age
都不會被改變众旗,也就是后面我修改的任意屬性值又不是響應(yīng)式了......不信的可以試試,我這里還沒有理解??趟畏,求大神給解釋贡歧。
解決方案
這里首先給出官方的解決方案:
this.$set(this.person,'name','zhao')
這句話加上之后如果this.person
的name
屬性沒有setter/getter
響應(yīng)方法,則會添加上赋秀,屬性為響應(yīng)式利朵。你可能以為這樣就可以了,然而事實(shí)還是在執(zhí)行方法時(shí)name屬性沒有改變??猎莲,因?yàn)槲覀兪前阉旁诎粹o點(diǎn)擊方法里的绍弟,所以最開始不會執(zhí)行這個(gè)地方,我們找找著洼。
問題在這里
created(){
this.person.name = 'liu'
this.person.age = '100'
},
由于這里是第一次給person
添加name
屬性,也沒有使用$set
方法晌柬,所以name
這里沒有setter
和getter
方法姥份,而后面再用$set
方法的時(shí)候,由于name
屬性已存在了年碘,所以$set
方法不會再進(jìn)行setter/getter
方法進(jìn)行響應(yīng)式監(jiān)測澈歉,這里一定要注意。
結(jié)論:
還是要細(xì)讀官方文檔屿衅,vue作者已經(jīng)在其中推薦盡量在data
初始化中將需要用到的屬性都寫出來埃难,這樣便于維護(hù)且可讀性更好。
如果data
中某屬性對應(yīng)初始值為{}
,且依然想要添加響應(yīng)式屬性的話涤久,用以下方法:
this.$set(this.objectProperty,'key',value)