<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
import { observe } from "./reactive"; import Watcher from "./watcher"; const data = { text: { innerText: { childText: "hello", }, }, }; observe(data); const updateComponent = () => { console.log(data.text.innerText.childText); }; new Watcher(updateComponent); data.text.innerText.childText = "liang";
我們的響應式系統到現在還沒有支援屬性是物件時候的響應,因此我們改變 的時候不會有任何輸出。childText
我們只收集了 的依賴,所以如果想要響應的話必須給 整個賦值為一個新物件。data.text
data.text
import { observe } from "./reactive"; import Watcher from "./watcher"; const data = { text: { innerText: { childText: "hello", }, }, }; observe(data); const updateComponent = () => { console.log(data.text.innerText.childText); }; new Watcher(updateComponent); data.text = { innerText: { childText: "liang", }, };
我們當然不希望每次都賦值整個物件,我們需要做一些修改,把巢狀的物件也變成響應式的。
我們只需要在給某個 重寫 和 之前,把它的 就像上邊給 呼叫 函數一樣,也呼叫一次 函數即可。key
get
set
value
data
observe
observe
同時提供 引數,留下擴充套件,讓外界決定是否需要深度響應。shallow
/*******************新增 shallow*******************/ export function defineReactive(obj, key, val, shallow) { /****************************************************/ const property = Object.getOwnPropertyDescriptor(obj, key); // 讀取使用者可能自己定義了的 get、set const getter = property && property.get; const setter = property && property.set; // val 沒有傳進來話進行手動賦值 if ((!getter || setter) && arguments.length === 2) { val = obj[key]; } const dep = new Dep(); // 持有一個 Dep 物件,用來儲存所有依賴於該變數的 Watcher /*******************新增****************************/ !shallow && observe(val); /******************************************************/ Object.defineProperty(obj, key, { enumerable: true, configurable: true, get: function reactiveGetter() { const value = getter ? getter.call(obj) : val; if (Dep.target) { dep.depend(); } return value; }, set: function reactiveSetter(newVal) { const value = getter ? getter.call(obj) : val; if (setter) { setter.call(obj, newVal); } else { val = newVal; } dep.notify(); }, }); }
同時,在 函數中,傳進來的 不是物件的話我們直接 。observe
value
return
/* util.js export function isObject(obj) { return obj !== null && typeof obj === "object"; } */ export function observe(value) { if (!isObject(value)) { return; } let ob = new Observer(value); return ob; }
import { observe } from "./reactive"; import Watcher from "./watcher"; const data = { text: { innerText: { childText: "hello", }, }, }; observe(data); const updateComponent = () => { console.log(data.text.innerText.childText); }; new Watcher(updateComponent); data.text.innerText.childText = "liang"; data.text = { innerText: { childText: "liang2", }, }; data.text.innerText.childText = "liang3";
可以一分鐘想一下上邊會輸出什麼。
new Watcher(updateComponent);
,執行一次 輸出 。updateComponent
hello
data.text.innerText.childText = "liang";
,我們已經解決了屬性是物件的情況,因此這裡也會輸出 。liang
data.text = { innerText: { childText: "liang2", }, };
上邊程式碼就是文章最開頭的方法,因此也會觸發函數執行,輸出 。liang2
data.text.innerText.childText = "liang3";
最後這句會執行嗎?
答案是否定的了,因為我們的 賦值為了一個新物件,但這個新物件我們並沒有將其設定為響應式的。data.text
因此我們需要在 的時候把物件也設定為響應式的。set
/** * Define a reactive property on an Object. */ export function defineReactive(obj, key, val, shallow) { const property = Object.getOwnPropertyDescriptor(obj, key); // 讀取使用者可能自己定義了的 get、set const getter = property && property.get; const setter = property && property.set; // val 沒有傳進來話進行手動賦值 if ((!getter || setter) && arguments.length === 2) { val = obj[key]; } const dep = new Dep(); // 持有一個 Dep 物件,用來儲存所有依賴於該變數的 Watcher let childOb = !shallow && observe(val); Object.defineProperty(obj, key, { enumerable: true, configurable: true, get: function reactiveGetter() { const value = getter ? getter.call(obj) : val; if (Dep.target) { dep.depend(); } return value; }, set: function reactiveSetter(newVal) { const value = getter ? getter.call(obj) : val; if (setter) { setter.call(obj, newVal); } else { val = newVal; } /******新增 *************************/ childOb = !shallow && observe(newVal); /************************************/ dep.notify(); }, }); }
通過遞迴解決了屬性是物件的依賴,可以為未來陣列的依賴留下基礎。
到此這篇關於Vue2 響應式系統之深度響應的文章就介紹到這了,更多相關Vue2 深度響應內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45