日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 前端技术 > vue >内容正文

vue

eltree ref什么时候有_Vue3响应式系统源码解析-Ref篇

發(fā)布時(shí)間:2023/12/4 vue 50 豆豆
生活随笔 收集整理的這篇文章主要介紹了 eltree ref什么时候有_Vue3响应式系统源码解析-Ref篇 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

文章轉(zhuǎn)載自:https://zhuanlan.zhihu.com/p/85978064

我們閱讀源碼的原因是什么?無非是1:學(xué)習(xí);2:更好的使用這個(gè)庫。如果只是想大致的了解下原理,倒不必花時(shí)間閱讀源碼,幾句話,幾張圖就能搞清楚,網(wǎng)上搜搜應(yīng)該就有很多。因此,閱讀源碼的過程一定是要對(duì)不明白的地方深入了解,肯定是很費(fèi)時(shí)間的。

在這過程中,有些知識(shí)點(diǎn),跟庫本身可能沒什么關(guān)系,但如果不懂,又難繼續(xù)理解。對(duì)于這些知識(shí)點(diǎn),我會(huì)盡量少的解釋,但會(huì)貼上盡量完善的文檔,方便不了解的同學(xué)先閱讀學(xué)習(xí)。

前言

在上篇文章中說道,ref是最影響源碼閱讀的文件。但如果不先搞明白它,看其他的只會(huì)更暈。我先幫大家理清ref的邏輯跟概念。

由于現(xiàn)在(2019/10/9)vue@3還未正式發(fā)版,大家還不熟悉其相關(guān)的用法。上篇文章雖然介紹了不少,但其實(shí)還是有不少疑問。在閱讀本篇文章之前,如果有時(shí)間,建議先閱讀Vue官方對(duì)Composition API的介紹: 1. Vue Composition API 2. Ref Vs Reactive

讀完關(guān)于Composition API的介紹,會(huì)對(duì)了解本庫有更多認(rèn)識(shí),便于更好的理解源碼。

ref跟reactive是整個(gè)源碼中的核心,通過這兩個(gè)方法創(chuàng)建了響應(yīng)式數(shù)據(jù)。要想完全吃透reactivity,必須先吃透這兩個(gè)。

Ref

ref最重要的作用,其實(shí)是提供了一套R(shí)ef類型,我們先來看,它到底是個(gè)怎么樣的數(shù)據(jù)類型。(為了更好的做解釋,我會(huì)調(diào)整源碼中的接口、類型、函數(shù)等聲明順序,并會(huì)增加一些注釋方便閱讀)

要想了解UnwrapNestedRefs與UnwrapRef,必須先要了解ts中的infer。如果之前不了解,請(qǐng)先閱讀相關(guān)文檔。看完文檔,再建議去google一些案例看看加深下印象。

現(xiàn)在我們假設(shè)你了解了infer概念,也了解了它的日常用法。再來看源碼:

如果還是懵,建議后續(xù)再去看看infer的相關(guān)介紹。在這我們直接拋結(jié)果:

Ref是這樣的一種數(shù)據(jù)結(jié)構(gòu):它有個(gè)key為Symbol的屬性做類型標(biāo)識(shí),有個(gè)屬性value用來存儲(chǔ)數(shù)據(jù)。這個(gè)數(shù)據(jù)可以是任意的類型,唯獨(dú)不能是被嵌套了Ref類型的類型。 具體來說就是不能是這樣 Array 或者這樣 { [key]: Ref }。但很奇怪的是,這樣Ref 又是可以的。具體為什么也不知道,所以我勇敢地提了個(gè)PR...

(果然Ref 是不夠完美的,2019.10.10晚,我這PR被合并了。大家遇到疑問時(shí),也可以勇敢的提PR,說不定就被合了....)

另外,Map、Set、WeakMap、WeakSet也是不支持解套的。說明Ref數(shù)據(jù)的value也有可能是Map這樣的數(shù)據(jù)類型。

說回Ref,從上篇文章中,我們已經(jīng)了解到,Ref類型的數(shù)據(jù),是一種響應(yīng)式的數(shù)據(jù)。然后我們看其具體實(shí)現(xiàn):

其實(shí)最難理解的就在于這個(gè)ref函數(shù)。我們看到,這里也定義了get/set,卻沒有任何Proxy相關(guān)的操作。在之前的信息中我們知道reactive能構(gòu)建出響應(yīng)式數(shù)據(jù),但要求傳參必須是對(duì)象。但ref的入?yún)⑹菍?duì)象時(shí),同樣也需要reactive做轉(zhuǎn)化。那ref這個(gè)函數(shù)的目的到底是什么呢?為什么需要有它?

在文章開頭,我貼了這份官方介紹Ref vs Reactive,這其中其實(shí)已經(jīng)說的很明白。

However, the problem with going reactive-only is that the consumer of a composition function must keep the reference to the returned object at all times in order to retain reactivity. The object cannot be destructured or spread:

對(duì)于基本數(shù)據(jù)類型,函數(shù)傳遞或者對(duì)象解構(gòu)時(shí),會(huì)丟失原始數(shù)據(jù)的引用,換言之,我們沒法讓基本數(shù)據(jù)類型,或者解構(gòu)后的變量(如果它的值也是基本數(shù)據(jù)類型的話),成為響應(yīng)式的數(shù)據(jù)。

// 我們是永遠(yuǎn)沒辦法讓`a`或`x`這樣的基本數(shù)據(jù)成為響應(yīng)式的數(shù)據(jù)的,Proxy也無法劫持基本數(shù)據(jù)。const a = 1;const { x: 1 } = { x: 1 }

但是有時(shí)候,我們確實(shí)就是想一個(gè)數(shù)字、一個(gè)字符串是響應(yīng)式的,或者就是想利用解構(gòu)的寫法。那怎么辦呢?只能通過創(chuàng)建一個(gè)對(duì)象,也即是源碼中的Ref數(shù)據(jù),然后將原始數(shù)據(jù)保存在Ref的屬性value當(dāng)中,再將它的引用返回給使用者。既然是我們自己創(chuàng)造出來的對(duì)象,也就沒必要使用Proxy再做代理了,直接劫持這個(gè)value的get/set即可,這就是ref函數(shù)與Ref類型的由來。

不過單靠ref還沒法解決對(duì)象解構(gòu)的問題,它只是將基本數(shù)據(jù)保持在一個(gè)對(duì)象的value中,以實(shí)現(xiàn)數(shù)據(jù)響應(yīng)式。對(duì)于對(duì)象的解構(gòu)還需要另外一個(gè)函數(shù):toRefs。

通過遍歷對(duì)象,將每個(gè)屬性值都轉(zhuǎn)成Ref數(shù)據(jù),這樣解構(gòu)出來的還是Ref數(shù)據(jù),自然就保持了響應(yīng)式數(shù)據(jù)的引用。但是源碼中有一點(diǎn)要注意,toRefs函數(shù)中引用的是toProxyRef而不是ref,它并不會(huì)在get/set中注入track跟trigger,也就是說,向toRefs傳入一個(gè)正常的對(duì)象,是不會(huì)返回一個(gè)響應(yīng)式的數(shù)據(jù)的。必須要傳遞一個(gè)已經(jīng)被reactive執(zhí)行返回的對(duì)象才能有響應(yīng)式的效果。感覺這點(diǎn)可以優(yōu)化,暫時(shí)也不知道小右這樣做的原因是什么。由于這里會(huì)牽扯到track跟trigger,而這兩個(gè)在我寫本文時(shí)還沒研究,就沒膽子提PR了。

到這,我們就把ref的源碼給看完了。

總結(jié)

以上是生活随笔為你收集整理的eltree ref什么时候有_Vue3响应式系统源码解析-Ref篇的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。