當咱們把一個數據傳給Vue實例data屬性完成視圖更新時,通過一番操做發現並無更新。
console
打印發現數據只是JavaScript普通對象數據。vue
緣由是由於Vue想要完成視圖響應必須把JavaScript普通對象數據轉爲具備getter/setter
的屬性對象數據。當調用setter
被調用時Vue捕獲數據從而完成響應組件更新。 Vue.js - 深刻響應式原理git
容許建立視圖響應的方式有:github
首先咱們準備兩組數據,,jsData
和vueData
。ui
const jsData = {
ja: "張三",
jb: "李四"
}
export default {
data() {
return {
vueData: {
va: "張三",
vb: "李四"
}
}
},
mounted() {
console.log(jsData, this.vueData);
},
// ...
}
複製代碼
運行能夠看出jsData
不在vue實例內建立,不具有getter/setter
,vueData
經過vue實例內data屬性建立初始屬性值從而具有getter/setter
。 this
視圖監測不到變化的實例以下:spa
export default {
// ...
mounted() {
console.log(jsData, this.vueData);
this.notAllow()
},
methods: {
notAllow() {
// demo 1
this.vueData.newKeyA = "keyA";
console.log(this.vueData);
// demo 2
// Object.assign(this.vueData, { newKeyA: "keyA" });
// console.log(this.vueData);
// demo 3
// this.vueData = Object.assign(this.vueData, { newKeyA: "keyA" });
// console.log(this.vueData);
}
}
}
複製代碼
上述代碼中都有一個問題,在同一個引用類型中插入數據,致使數據對象自己沒有改變,也就意味着Vue檢查不到數據內存指向作更改,這就會致使插入的只是不具有getter/setter
的屬性。code
運行結果: cdn
export default {
mounted() {
console.log(jsData, this.vueData);
this.allow()
},
methods: {
allow() {
// demo 1
this.vueData = {
...this.vueData,
newKeyA: "keyA"
}
console.log(this.vueData);
// demo 2
// this.$set(this.vueData, "newKeyA", "keyA");
// console.log(this.vueData);
}
}
}
複製代碼
上述demo1的方式是替換一個內存指向完成數據變化。 demo2是經過Vue實例提供的$set方法, 在不改變內指向的同時,添加一個的具有getter/setter
屬性作了補充。對象
運行結果: blog
本文提供demo見:GitHub
*