vue next 響應式原理

2022-07-11 02:48:09 字數 3017 閱讀 6975

最新 vue-next 的原始碼發布了,雖然是 pre-alpha 版本,但這時候其實是閱讀原始碼的比較好的時機。在 vue 中,比較重要的東西當然要數它的響應式系統,在之前的版本中,已經有若干篇文章對它的響應式原理和實現進行了介紹,這裡就不贅述了。在 vue-next 中,其實現原理和之前還是相同的,即通過觀察者模式和資料劫持,只不過對其實現方式進行了改變。

對於解析原理的文章,我個人是比較喜歡那種「小白」風格的文章,即不要摘錄特別多的**,也不要闡述一些很深奧的原理與概念。在我剛接觸 react 的時候,還記得有一篇利用 jquery 來介紹 react 的文章,從簡入繁,面面俱到,其背後闡述的知識點對我後來學習 react 起到很多的幫助。

如有錯誤,還望指正。

我們大體要實現的效果如下面的**所示:

// 實現兩個方法 reactive 和 effect

const state = reactive()

effect(() => )

state.count++ // 輸入 count: 1

可以發現我們熟悉的依賴收集階段(同時也是觀察者模式的訂閱過程),是在 effect 中進行的,依賴收集的準備工作(即資料劫持邏輯),是在 reactive 中進行的,而資料變化的觸發響應的邏輯在後面的 state.count++ **執行時進行(同時也是觀察者模式的發布過程),之後便會執行之前傳入 effect 內部的**函式並輸入 count: 1。

由於 vue-next 用 ts 進行了重寫,這裡我也使用 ts 來實現這個極簡版本的響應式系統。主要涉及到的型別和公共變數如下:

type effect = function;

type effectmap = map;

let currenteffect: effect;

const effectmap: effectmap = new map();

在之前的版本中,vue 利用 object.defineproperty 中的 setter 和 getter 來對資料物件進行劫持,vue-next 則通過 proxy。眾所周知,object.defineproperty 所實現的資料劫持是有一定限制的,而 proxy 就會強大很多。

首先,我們在腦後中,設想一下如何使用 proxy 來實現資料劫持呢?很簡單,大體結構如下所示:

export function reactive(obj) 

這裡的 handlers 是宣告如何處理各個 trap 的邏輯,比如:

const handlers = ,

set: function(target, key, value, receiver) ,

deleteproperty(target, key)

// ...以及其他 trap

}

由於這裡是極簡版本的實現,那麼我們就僅僅實現 get 和 set 兩個 trap 就可以了,分別對應依賴收集和觸發響應的邏輯。

對於依賴收集的實現,由於是極簡版本,實現的前提如下:

哈哈,基本這四點排除之後,這個依賴收集函式就會很輕很薄,如下:

function(target, key: string, receiver) 

} else

}return reflect.get(target, key, receiver);

}

實現的邏輯很簡單,其實就是觀察者模式中註冊訂閱者的實現邏輯,值得注意的是,這裡對於 target 的賦值邏輯,我們委託給 reflect 來完成,雖然 target[key] 也是可以工作的,但是使用 reflect 是更提倡的方式。

觸發響應的邏輯就比較簡單了,其實是對應觀察者模式中,發布事件的邏輯,如下:

function(target, key: string, value, receiver) 

return result;

}

同樣,這裡使用 reflect 來對 target 進行賦值操作,因為它會返回乙個 boolean 值代表是否成功,而 set 這個 trap也需要代表相同含義的值。

實現了資料劫持的**邏輯之後,我們只需要在 reactive 這個方法中,返回乙個**物件的例項即可,還記的上文中我們在實現之前腦海中浮現的大致**框架嗎?

如下:

export function reactive(obj: any) 

} else

}return reflect.get(target, key, receiver);

},set: function(target, key: string, value, receiver)

return result;

}});

return proxied;

}

上文中提到了,對於依賴收集的工作,我們是有條件地進行的,即在乙個 effect 中,我們才會進行收集,其他情況下的取值邏輯,我們則不會進行依賴收集,因此,effect 方法正式為了實現這點而存在的,如下:

export function effect(fn: function) ;

currenteffect = effected;

effected();

currenteffect = undefined;

return effected;

}

之所以實現如此簡單,是因為我們這裡是極簡版本,不需要考慮諸如 readonly 、異常以及收集時機等因素。可以發現,就是將傳入的**函式包裹在另乙個方法中,然後將這個方法用 currenteffect 這個變數暫存,之後嘗試執行一下即可。當 effect 執行完畢之後,再將 currenteffect 置空,這樣就可以達到只在 effect 下進行依賴收集的目的。

資源搜尋**大全

廣州vi設計公司

這個極簡的響應式系統雖然能用,但是有很多未考慮的因素,其實就是在上文中被我們忽略的那些前提條件,這裡再列舉一下,並給出源**中的解法:

vue響應式布局 Vue 響應式原理

vue2 的資料偵測 在 src observer 目錄裡面,元件例項在初始化時,會呼叫 observe 函式處理 data function initdata vm observe 改寫了所有物件屬性的 getter setter 和陣列原型上的 7 個會改寫陣列方法,從而讓 data 變成可響應...

vue響應式原理

響應式系統是vue框架核心的部分,資料物件僅僅是普通的 js物件。當我們改變資料時,檢視也會被改變,本文就來 一下vue 的響應式原理。vue響應式的核心是使用了es5 新增的api object.defineproperty 因此vue不支援ie8 object.defineproperty的作用...

vue響應式原理

要了解響應式原理首先應該知道什麼是響應式 更改 vue的響應式原理是什麼 vue資料的雙向繫結是通過資料劫持結合發布訂閱模式,偵測到資料變化,然後通過object.defineproperty 物件對每個屬性的getter和setter進行劫持。當讀取 data 中的資料時自動呼叫 get 方法,當...