淺談Vue.set實際上是什么
談到Vue.set就要說響應(yīng)式原理,所以得為你自己準(zhǔn)備下這方面的理論知識。然而,一如即往,這并不難或者枯燥。準(zhǔn)備點鱷梨和薯條,制作些鱷梨醬,然后我們再進(jìn)入話題。
數(shù)據(jù)和響應(yīng)式原理
在一個Vue組件中,無論你何時創(chuàng)建一個data()功能屬性,都會返回一個對象。Vue在組件背后做了很多事情,來使得它具有響應(yīng)式。
export default {
data() {
return {
red: 'hot',
chili: 'peppers'
}
}
}
Vue要做的第一件事是使用我們超帥的RHCP(Red Hot Chili Peppers, 一個超贊的樂隊)data,它遍歷了return {}對象的屬性properties,然后為它們創(chuàng)建了唯一的getter和setter。具體情況已經(jīng)超出了本文的范圍,但是Vue Mastery有個很贊的視頻去解析這點。
創(chuàng)建這些屬性的目的是使你在代碼中訪問這些屬性時(例如通過執(zhí)行this.red或使用this.red=hotter進(jìn)行設(shè)置時),實際上是在調(diào)用Vue為你創(chuàng)建的getter和setter。
在SETGET這塊神奇的土地上,Vue連接起了computer properties, watchers, props,data等,從而變得響應(yīng)式。以非常簡單的方式,它被稱為一個函數(shù),該函數(shù)在每次setter改變時更新整個工作。
陷阱
酷極了!這就是我們喜歡Vue的原因,它具有響應(yīng)式和強(qiáng)大的幕后功能。但是也有一些陰暗面需要我們探討。
在我們開始之前,我們更改下data數(shù)據(jù)看發(fā)生什么。
data() {
return {
members: {}
}
}
好吧,到目前為止沒什么看頭,我們在data中有一個member屬性,用來添加樂隊成員的信息?,F(xiàn)在,為了舉例,我們添加一個方法,并假裝從遠(yuǎn)程http請求中拉取一些信息,它將返回一個樂隊信息的JSON對象。
data() {
return {
members: {}
}
},
methods: {
getMembers() {
const newMember = {
name: 'Flea',
instrument: 'Bass',
baeLevel: 'A++'
}; // Some magical method that gives us data got us this sweet info
// ...
}
}
嗯。好吧,我們先停停然后思考下這個例子。如何將newMember對象添加到當(dāng)前的member屬性中?這有許多方法可以解決當(dāng)前的難題。
也許你會想,我們可以將member轉(zhuǎn)換成一個數(shù)組,然后將它push進(jìn)去。這可行,但是這是在作弊,因為它破壞了我開始輸入時細(xì)心構(gòu)造的例子。
在這種情況下,我們member是一個object。好吧,簡單,你會說,我們在member上添加一新的屬性,這樣它還是一個object。實際上,我們在member上添加個name屬性。
getMembers() {
const newMember = {
name: 'Flea',
instrument: 'Bass',
baeLevel: 'A++' // Totally important property that we will never use
}; // Some magical method that gives us data got us this sweet info
this.members[newMember.name] = newMember;
}
Lok'tar Ogar!(不勝則亡)
可是,不,因為-
A. 這不是Orgrimmar(魔獸世界人物)
B. 現(xiàn)在我們遇到問題了
如果你在瀏覽器上測試這段代碼,你將看到你確實將新數(shù)據(jù)推入member數(shù)據(jù)中了,但是此次的更改組件的狀態(tài)將不會使得你的應(yīng)用重新渲染。
僅將這些數(shù)據(jù)用于某些計算或某種內(nèi)部存儲的情況下,以這種方式進(jìn)行操作不會影響你的應(yīng)用程序。然而,這里應(yīng)該是大大的轉(zhuǎn)折HOWERVER,如果你在自己app上正在使用這種數(shù)據(jù)去展示數(shù)據(jù),或者根據(jù)條件v-if或v-else來渲染,事情將變得有趣。
實際使用Vue.set
所以,現(xiàn)在我們明白問題實際出在哪里了,我們可以學(xué)習(xí)什么是正確的解決方案。允許我向你介紹Vue.set。
Vue.set是一個工具,它允許我們向已經(jīng)激活的對象添加新屬性,然后確保這個新的屬性也是響應(yīng)的。
這完全解決了我們在另一個例子中遇到的問題,因為當(dāng)我們設(shè)置member的新屬性時,它將自動掛接到Vue的響應(yīng)式系統(tǒng)中,酷酷的getters/setters和Vue的魔法都在框架背后運(yùn)行。
但是,需要一點說明來了解它如何影響數(shù)組。到目前為止,我們只是試驗過了objects,這很容易理解。新的屬性?如果你希望它是響應(yīng)式,則通過Vue.set添加。簡單~
延續(xù)上面的示例,我們切換為使用Vue.set的方式。
getMembers() {
const newMember = {
name: 'Flea',
instrument: 'Bass',
baeLevel: 'A++'
}; // Some magical method that gives us data got us this sweet info
//this.members[newMember.name] = newMember;
this.$set(this.members, newMember.name, newMember);
}
這是新添加的this.$set(this.members, newMember.name, newMember);。
對于這段代碼,我有兩點想提下。目前為止,我告訴了你Vue.set是怎樣工作的,但是現(xiàn)在我使用this.$set,但是不要擔(dān)心,這只是個別名,所以它會以完全相同的方式運(yùn)行。比較酷的是你不用在你的組件中引入Vue。
我想說的第二點是這個函數(shù)的語法。它需要傳入三個參數(shù),第一個參數(shù)是我們要改變的object或array(案例上是this.members)。
第二個參數(shù)是指向我們傳入第一個參數(shù)object/array的property或key(這里是newMember.name,因為我們想動態(tài)生成)。
最后是第三個參數(shù),它是我們想要設(shè)置的值(在案例中,newMember)。
this.members [newMember.name] = newMember;
// V V V
this.$set(this.members, newMember.name, newMember);
(PS. My ASCII skills are not for sale )
但是數(shù)組的響應(yīng)如何?
當(dāng)我們在最初的狀態(tài)中創(chuàng)建一個array,Vue將它設(shè)置為響應(yīng)式,然而,當(dāng)你直接通過索引賦值,當(dāng)前Vue不能檢測到。例如,我們?nèi)缦虏僮鳎?br />
this.membersArray[3] = myNewValue;
然而,Vue不能檢測到這種更改,因此它不是響應(yīng)式的。請銘記于心,如果你通過pop,splice,push操作來更改數(shù)組,那么這些操作將觸發(fā)數(shù)組的響應(yīng)式,所以你可以安全地使用它們。
在必要的時候我們需要直接通過索引賦值,我們可以使用Vue.set。我們看下它和之前的例子有什么區(qū)別。
this.$set(this.membersArray, 3, myNewValue)
如果你想了解更多響應(yīng)式原理的注意點,請移步[link to the official documentation](https://vuejs.org/v2/guide/list.html#Caveats) 。
Vue 3.0
在編寫這篇文章時,這一切仍然可能更改,但是現(xiàn)在滿大街都在說這些警告將不再是問題。換言之,Vue 3.0會讓你完全忘記這些邊緣的案例,除了那些可憐的人兒,他們必須要針對某些不能完全支持新響應(yīng)式系統(tǒng)的舊瀏覽器。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
深入探索VueJS Scoped CSS 實現(xiàn)原理
這篇文章主要介紹了深入探索VueJS Scoped CSS 實現(xiàn)原理,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-09-09
vue elementui select標(biāo)簽監(jiān)聽change事件失效問題
這篇文章主要介紹了vue elementui select標(biāo)簽監(jiān)聽change事件失效問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-04-04
vant中l(wèi)ist的使用以及首次加載觸發(fā)兩次解決問題
這篇文章主要介紹了vant中l(wèi)ist的使用以及首次加載觸發(fā)兩次解決問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-10-10

