摘要:當東西發售時,就會打你的電話通知你,讓你來領取完成更新。其中涉及的幾個步驟,按上面的例子來轉化一下你買東西,就是你要使用數據你把電話給老板,電話就是你的,用于通知老板記下電話在電話本,就是把保存在中。剩下的步驟屬于依賴更新
寫文章不容易,點個贊唄兄弟
專注 Vue 源碼分享,文章分為白話版和 源碼版,白話版助于理解工作原理,源碼版助于了解內部詳情,讓我們一起學習吧
研究基于 Vue版本 【2.5.17】
如果你覺得排版難看,請點擊 下面鏈接 或者 拉到 下面關注公眾號也可以吧
【Vue原理】依賴收集 - 源碼版之基本數據類型
如果對依賴收集完全沒有概念的同學,可以先看我這篇
【Vue原理】響應式原理 - 白話版
依賴收集,主要是為了解決一個問題,什么問題呢?
首先,我們都知道,Vue 的數據是響應式更新的,一旦數據改變了,那么相應使用到 數據的地方也會跟著改變。
那么問題來了,數據改變的時候,Vue 怎么知道,去讓那些使用到數據的地方也改變呢?
這就是依賴收集要解決的問題!
他是怎么解決的?簡單說就是把依賴了數據的地方,給集中收集起來以便變化后通知!我們今天來看源碼的流程
首先,響應式更新,分為兩步,依賴收集和依賴更新
今天講的是依賴收集,如何去收集 使用了數據的地方
依賴收集,又分為兩個流程
1、數據初始化流程
2、依賴收集流程
當前篇,先以基本數據類型為例講解,因為 基本數據和 引用數據 在處理上有很大的不同,引用類型需要理解的東西更多更復雜,所以需要循序漸進,分兩篇描述
數據初始化流程首先,在實例初始化的時候,需要對數據進行響應式處理,也就是給每個屬性都使用 Object.defineProperty 處理
處理的流程是怎么樣的呢?
1、實例初始化中,調用 initState 處理部分選項數據,initData 用于處理選項 data
Vue.prototype._init=function(){ ... initState(this) ... } function initState(vm) { var opts = vm.$options; ... props,computed,watch 等選項處理 if (opts.data) { initData(vm); } };
2、initData 遍歷 data,definedReactive 處理每個屬性
function initData(vm) { var data = vm.$options.data; data = typeof data === "function" ? data.call(vm, vm) : data || {}; // ... 遍歷 data 數據對象的key,重名檢測,合規檢測等代碼 new Observer(data); } function Observer(value) { var keys = Object.keys(value); // ...被省略的代碼 for (var i = 0; i < keys.length; i++) { defineReactive(obj, keys[i]); } };
3、definedReactive 給對象的屬性 通過 Object.defineProperty 設置響應式
function defineReactive(obj, key) { // dep 用于中收集所有 依賴我的 東西 var dep = new Dep(); var val = obj[key] Object.defineProperty(obj, key, { enumerable: true, configurable: true, get() { ...依賴收集,詳細源碼下個流程放出 }, set() { ....依賴更新,源碼下篇文章放出 } }); }依賴收集流程
寫一個小例子來解析
new Vue({ el: document.getElementsByTagName("div")[0], data(){ return { name:11 } } })
頁面模板
頁面引用了數據 name,name 需要保存 頁面的watcher,以便于 name 變化時,通知 頁面watcher 更新
1、頁面渲染函數
with(this){ return _c("div",{},[name]) }
2、讀取 name
渲染函數執行,上下文對象綁定為 實例,于是name讀取到實例上的 name
3、保存 watcher
name 被讀取,自然走到 Object.defineProperty.get 方法上,從這里開始收集 watcher
先來觀察下 defineReactive 中省略的 get 的源碼
function defineReactive(obj, key) { var dep = new Dep(); var val = obj[key] Object.defineProperty(obj, key, { get() { if (Dep.target) { // 收集依賴 dep.addSub(Dep.target) } return val } }); }
哈哈哈,這里就有意思了,這段代碼就是 依賴收集的核心,主要是三個點
Dep.target
Dep
dep.addSub
1、Dep.target
Dep.target 指向的是各種 watcher,watch的watcher,頁面的watcher 等等
Dep.target 是變化的,根據當前解析流程,不停地指向不同的 watcher (指向,其實就是直接賦值 ,如下)
Dep.target = 具體watcher
“當然沒有這么簡單,就是表示一個意思而已”
簡單想,指向哪個watcher,那么就是那個 watcher 正在使用數據,數據就要收集這個watcher
你可以先不用管 Dep.target 到底是怎么指向,你只用記住 在 watcher
比如當前頁面開始渲染時,Dep.target 會提前指向當前頁面的 watcher。
于是頁面渲染函數執行,并引用了數據 name 后,name 直接收集 Dep.target,就會收集到當前頁面的 watcher
watcher 有負責實例更新的功能,所以會被收集起來,數據變化時通知 watcher,就可以調用 watcher 去更新了
watcher 在 依賴收集中只起到被收集的作用,所以不會在這里詳細解釋
2、Dep
Dep 是一個構造函數,用于創建實例,并帶有很多方法
實例會包含一個屬性 subs 數組,用于存儲不同數據 【收集的依賴】
看下dep的構造函數
var Dep = function Dep() { // 保存watcher 的數組 this.subs = []; };
3、dep.addSub
原型上的方法,作用是往 dep.subs 存儲器中 中直接添加 watcher
Dep.prototype.addSub = function(sub) { this.subs.push(sub); };
所以,【dep.addSub(Dep.target) 】就會直接添加當前 watcher
于是,收集流程大概是這樣
1、頁面的渲染函數執行, name 被讀取
2、觸發 name的 Object.defineProperty.get 方法
3、于是,頁面的 watcher 就會被收集到 name 專屬的閉包dep 的 subs 中
總結為什么需要依賴收集,之前也已經說過,是為了變化時通知 那些使用過數據的地方
就好比,你去商店買東西,東西還沒有發售,于是你把你的電話給老板,老板把你的記在電話本上。當東西發售時,就會打你的電話通知你,讓你來領取(完成更新)。
其中涉及的幾個步驟,按上面的例子來轉化一下
1、你買東西,就是你要使用數據 name
2、你把電話給老板,電話就是你的 watcher,用于通知
3、老板記下電話在電話本,就是把 watcher 保存在 subs 中。
4、剩下的步驟屬于依賴更新
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/109953.html
摘要:寫文章不容易,點個贊唄兄弟專注源碼分享,文章分為白話版和源碼版,白話版助于理解工作原理,源碼版助于了解內部詳情,讓我們一起學習吧研究基于版本如果你覺得排版難看,請點擊下面鏈接或者拉到下面關注公眾號也可以吧原理依賴收集源碼版之引用數據類型上 寫文章不容易,點個贊唄兄弟專注 Vue 源碼分享,文章分為白話版和 源碼版,白話版助于理解工作原理,源碼版助于了解內部詳情,讓我們一起學習吧研究基于...
摘要:寫文章不容易,點個贊唄兄弟專注源碼分享,文章分為白話版和源碼版,白話版助于理解工作原理,源碼版助于了解內部詳情,讓我們一起學習吧研究基于版本如果你覺得排版難看,請點擊下面鏈接或者拉到下面關注公眾號也可以吧原理依賴更新源碼版如果對依賴收集完 寫文章不容易,點個贊唄兄弟專注 Vue 源碼分享,文章分為白話版和 源碼版,白話版助于理解工作原理,源碼版助于了解內部詳情,讓我們一起學習吧研究基于...
寫文章不容易,點個贊唄兄弟專注 Vue 源碼分享,文章分為白話版和 源碼版,白話版助于理解工作原理,源碼版助于了解內部詳情,讓我們一起學習吧研究基于 Vue版本 【2.5.17】 如果你覺得排版難看,請點擊 下面鏈接 或者 拉到 下面關注公眾號也可以吧 【Vue原理】Props - 源碼版 今天記錄 Props 源碼流程,哎,這東西,就算是研究過了,也真是會隨著時間慢慢忘記的。 幸好我做...
摘要:因為失去焦點之后被強制更新了一波嗯,這就是的作用,把頁面上的顯示值也過濾一遍 寫文章不容易,點個贊唄兄弟專注 Vue 源碼分享,文章分為白話版和 源碼版,白話版助于理解工作原理,源碼版助于了解內部詳情,讓我們一起學習吧研究基于 Vue版本 【2.5.17】 如果你覺得排版難看,請點擊 下面鏈接 或者 拉到 下面關注公眾號也可以吧 【Vue原理】VModel - 源碼版之input詳...
摘要:我們都知道分為普通和作用域,兩個內容都很多,所以分兩部分進行講述。今天講的是普通其實普通,表示默認和具名,只是他們的處理方式都差不多,就只是是否有自定義名字而已,所以,表示一種類型。 寫文章不容易,點個贊唄兄弟專注 Vue 源碼分享,文章分為白話版和 源碼版,白話版助于理解工作原理,源碼版助于了解內部詳情,讓我們一起學習吧研究基于 Vue版本 【2.5.17】 如果你覺得排版難看,請...
閱讀 767·2023-04-25 15:13
閱讀 1388·2021-11-22 12:03
閱讀 816·2021-11-19 09:40
閱讀 1898·2021-11-17 09:38
閱讀 1702·2021-11-08 13:18
閱讀 649·2021-09-02 15:15
閱讀 1760·2019-08-30 15:54
閱讀 2623·2019-08-30 11:12