談到Vue.set
就要說響應式原理,因此得爲你本身準備下這方面的理論知識。然而,一如即往,這並不難或者枯燥。準備點鱷梨和薯條,製做些鱷梨醬,而後咱們再進入話題。javascript
在一個Vue
組件中,不管你什麼時候建立一個data()
功能屬性,都會返回一個對象。Vue
在組件背後作了不少事情,來使得它具備響應式。html
export default {
data() {
return {
red: 'hot',
chili: 'peppers'
}
}
}
複製代碼
Vue
要作的第一件事是使用咱們超帥的RHCP(Red Hot Chili Peppers, 一個超讚的樂隊)data
,它遍歷了return {}
對象的屬性properties
,而後爲它們建立了惟一的getter
和setter
。具體狀況已經超出了本文的範圍,可是Vue Mastery有個很讚的視頻去解析這點。vue
建立這些屬性的目的是使你在代碼中訪問這些屬性時(例如經過執行this.red
或使用this.red=hotter
進行設置時),其實是在調用Vue
爲你建立的getter
和setter
。java
在SETGET
這塊神奇的土地上,Vue
鏈接起了computer properties, watchers, props,data
等,從而變得響應式
。以很是簡單的方式,它被稱爲一個函數,該函數在每次setter
改變時更新整個工做。react
酷極了!這就是咱們喜歡Vue
的緣由,它具備響應式和強大的幕後功能。可是也有一些陰暗面須要咱們探討。git
在咱們開始以前,咱們更改下data
數據看發生什麼。github
data() {
return {
members: {}
}
}
複製代碼
好吧,到目前爲止沒什麼看頭,咱們在data
中有一個member
屬性,用來添加樂隊成員的信息。如今,爲了舉例,咱們添加一個方法,並僞裝從遠程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
對象添加到當前的member
屬性中?這有許多方法能夠解決當前的難題。瀏覽器
也許你會想,咱們能夠將member
轉換成一個數組,而後將它push
進去。這可行,可是這是在做弊,由於它破壞了我開始輸入時細心構造的例子。安全
在這種狀況下,咱們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. 如今咱們遇到問題了
若是你在瀏覽器上測試這段代碼,你將看到你確實將新數據推入member
數據中了,可是這次的更改組件的狀態將不會使得你的應用從新渲染。
僅將這些數據用於某些計算或某種內部存儲的狀況下,以這種方式進行操做不會影響你的應用程序。然而,這裏應該是大大的轉折HOWERVER
,若是你在本身app
上正在使用這種數據去展現數據,或者根據條件v-if
或v-else
來渲染,事情將變得有趣。
因此,如今咱們明白問題實際出在哪裏了,咱們能夠學習什麼是正確的解決方案。容許我向你介紹Vue.set
。
Vue.set
是一個工具,它容許咱們向已經激活的對象添加新屬性,而後確保這個新的屬性也是響應的。
這徹底解決了咱們在另外一個例子中遇到的問題,由於當咱們設置member
的新屬性時,它將自動掛接到Vue
的響應式系統中,酷酷的getters/setters
和Vue
的魔法都在框架背後運行。
可是,須要一點說明來了解它如何影響數組。到目前爲止,咱們只是試驗過了objects
,這很容易理解。新的屬性?若是你但願它是響應式,則經過Vue.set
添加。簡單~
延續上面的示例,咱們切換爲使用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
是怎樣工做的,可是如今我使用this.$set
,可是不要擔憂,這只是個別名,因此它會以徹底相同的方式運行。比較酷的是你不用在你的組件中引入Vue
。
我想說的第二點是這個函數的語法。它須要傳入三個參數,第一個參數是咱們要改變的object
或array
(案例上是this.members
)。
第二個參數是指向咱們傳入第一個參數object/array
的property
或key
(這裏是newMember.name
,由於咱們想動態生成)。
最後是第三個參數,它是咱們想要設置的值(在案例中,newMember
)。
this.members [newMember.name] = newMember;
// V V V
this.$set(this.members, newMember.name, newMember);
複製代碼
(PS. My ASCII skills are not for sale )
可是數組的響應如何?
當咱們在最初的狀態中建立一個array
,Vue
將它設置爲響應式,然而,當你直接經過索引賦值,當前Vue
不能檢測到。例如,咱們以下操做:
this.membersArray[3] = myNewValue;
複製代碼
然而,Vue
不能檢測到這種更改,所以它不是響應式的。請銘記於心,若是你經過pop
,splice
,push
操做來更改數組,那麼這些操做將觸發數組的響應式,因此你能夠安全地使用它們。
在必要的時候咱們須要直接經過索引賦值,咱們可使用Vue.set
。咱們看下它和以前的例子有什麼區別。
this.$set(this.membersArray, 3, myNewValue)
複製代碼
若是你想了解更多響應式原理的注意點,請移步[link to the official documentation](vuejs.org/v2/guide/li…)。
在編寫這篇文章時,這一切仍然可能更改,可是如今滿大街都在說這些警告將再也不是問題。換言之,Vue 3.0
會讓你徹底忘記這些邊緣的案例,除了那些可憐的人兒,他們必需要針對某些不能徹底支持新響應式系統的舊瀏覽器。