前言
我們知道Vue框架劇本雙向資料系結功能,在我們使用方便的同時,還有一些細節問題我們并不知道,接下來一起探討一些吧
雙向資料系結
- js變數改變影響頁面
- 頁面改變影響js變數
Vue2是如何做到資料系結的
Object.defineProperty(obj,key,{
set:function (newV) {
val = newV;
// 通知所有用到這個屬性的DOM更新
dep.notifyAll();
},
get:function () {
if (Dep.currentSub) {
// 對這個屬性,新訂閱一個元素
dep.subscribe();
}
return val;
}
});
- 以上需要說的就是: Vue中data函式回傳的物件,會經過層層遍歷,最后將所有的物件通過以上方法,把其屬性進行監視,
- 通過xxx.xxx = 'xxx' 就會觸發set函式
- 通過xxx.xxx 就會觸發get函式
關于陣列與基本資料型別的奇葩現象
我們宣告好陣列,其中放置基本資料型別
let vm = new Vue({
el:'#app',
template:`
<div>
<p v-for="n in arr" >
{{n}}
</p>
</div>`,
data(){
return {
arr:[1,2,3]
}
}
});
現在我們改變其中的元素值

- 如圖所見,我們改變陣列中某個元素的值,并未發現頁面改變

解答疑問
- 首先我們知道作為data的屬性,Vue都會通過for in 來遍歷該物件的所有屬性及子屬性,然后針對每個屬性進行reactive式的資料劫持,
- 但是當遍歷陣列或物件屬性時,如果是非物件資料型別,就如下圖

- 我們可以看到在Vue中 對于reactive操作,非物件資料型別是不管的,因此,我們更改vm.arr[0] = 98沒有效果
想辦法解決
聽說有個函式可以讓Vue知道你在添加屬性,并完成回應式,Vue.set(obj.key.value);
哇,有效果!!
我們再來改變他看看是否能雙向資料系結

哦! No!看看原始碼

看到了嗎? 基本(原始)資料型別還給個警告!!

往下執行,如果是陣列直接結束了,并不做reactive操作哦
總結
之前講解了Vue做資料劫持是基于Object.defineProperty的,但是他只能做set和get,而無法監視到屬性的增加或者減少,這點倒是可以用Vue.set(obj.key.value)解決!而陣列+基本資料型別不行! 當然話說回來,真實業務中,直接用陣列操作基本資料型別的場景還真不多!

轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/147694.html
標籤:JavaScript
上一篇:vue 路由過渡動效
