JavaScript進階(十九):proxy 的應用(二)

這篇博客,我們就把這個 proxy 給真正的用起來。

我們先看下原來的 HotList:

我們一直來回折騰這個東西,倒不是因爲別的,而是因爲這個東西足夠簡單,足夠支撐我們很多東西。

那麼現在這時候,我們就稍微的把它改一改,我們直接在 defineProperty 版本的基礎上改。

 

首先,_updated 和 $set 可以刪了,它只是爲了迎合 defineProperty 而做的:

然後現在有幾個問題:

首先,_getRoot 不用動,我們需要改的主要是 _defineDate 這一塊。

現在這個 _defineData,我們就不用循環了,我們創建好 data 之後,直接把 data 給 return 出去就好了:

這時候大家可能覺得有點奇怪,你 return 這個 data 幹啥?我們先來看看接下來的一個寫法。

首先,我現在需要的是這樣的:

我們在 render 裏面,用到了一系列的 data.href,data.vip,等等 data 點什麼,那麼這個 data 來自於哪?

它來自於 this.data:

然後我們現在既然已經不用 defineProperty 了,那麼首先,我們先把它名字改了。

把 _defineData 改爲 _getData,它是用來獲取這個數據的:

然後這個時候,先不管別的,我們先把它保存起來:

這個是我們目前爲止,這個對象身上所有的數據

那麼這個時候,它能正常工作嗎?

肯定是不行的,爲什麼?

因爲我們現在改名叫 _data,所以但凡是用到 data 或者 title 的時候,都不行了:

所以我們得這麼幹,改成 this._data.xxx:

這個時候你可以看到東西都出來了。

然後我們試一下,我現在想要去設置它的數據:

注意,這時候有兩個問題:

1,我們現在用這個寫法 list._data.xxx = 'xxx',它用起來方便嗎?

一點都不方便。

2,我設置了 title,頁面上也沒有任何變化。

但是你可以看到,_data 裏面的 title 是真變了,但它不會重新渲染。

 

那麼我們就以這爲起點,我們來繼續往下做。

首先就是我現在這個東西用起來不方便,它叫 _data,這個還不如之前的 defineProperty 好,爲什麼?

因爲之前 defnieProperty,它所有的那些數據,就像是我對象的一部分一樣,我直接用 this.title,this.data,我直接去用 this 上面的各種東西,這個肯定很方便。

那怎麼解決呢?

 

首先,我們可不可以把這個 this,如果看做是一個 proxy,是不是就沒有問題了?我們可以用它來獲取。

那麼這時候,我們直接做一個事,我就這麼寫,行不行?

這個是肯定不行的,你可以看到,當我這麼去寫的時候,它直接給我報錯了。

它說,this 是不能賦值的。

實際上來說,this 是真的不能賦值,所以你就不能這麼幹。那這時候怎麼辦?其實也挺簡單的。

 

首先,我們要的是什麼?

構造函數 constructor 裏面方不方便我們再說,我們重點,要的是其他的操作,比如 render,要讓它們方便。

可以讓它們直接去用 this.title,this.data 等等:

這是需要我們去優化的。

 

那麼這時候問題就來了,怎麼做?

前面的博客中,我們有說過,proxy 它可以接管我們的 constructor 等等這一系列的東西。

那麼既然可以接管這一套東西,那麼我們能不能這麼寫,把整個 class 給它包起來:

這個跟我們前面博客中是一樣的,只不過這個 class 大了一點而已。

然後這個 new 出來的 proxy,它纔是我以後,真正用來當做 HotList 用的那個東西:

然後 proxy 的第一個參數 class 有了。

那麼現在,我們就需要第二個參數,讓它有一些可以監聽的地方,比方說 construct:

那麼 args 有什麼?有 data。

所以我們現在的 constructor 裏面,就不要再去加這些數據了,以及我們的初始渲染也不做了。

爲什麼?

因爲在 constructor 構造函數裏面,我並不能直接得到那個 data。

所以我需要讓 proxy 幫我把那個 data 給變出來。

 

那麼首先,在 construct 裏面,和之前的套路是一樣的。

我需要來 new 一個 class,並且把 args 作爲參數拿過來:

然後現在我就可以得到一個 obj。

這時候,我的這個 obj,它裏面本身是沒有數據的。

如果我直接就把它 return 出去了,行嗎?

這個時候你可以發現,什麼都出不來,因爲它現在也沒調用 render 了。

那麼這時候可能有人會說,沒關係,我們先給它 render 一下:

這時候你可以發現,不行。

它會告訴你,我找不到這些屬性。

因爲數據就不存在。

那怎麼辦?

以前的時候,我們完全是讓 _getData 來幫我們來完成數據的處理:

但現在其實不用。

我們完全可以把整個 _getData 拿到 construct 裏面來做事。

先不管好不好看,我們就管這事能不能出來:

然後我們再來做一個事,既然數據已經有了,那麼我們 console 出來看看:

可以看到,data 裏面的 data、title 都有,那麼接下來怎麼辦?

我們可不可以先循環所有的 data,然後直接給它加到 obj 的身上去:

可以看到,現在頁面能出來,沒問題。

但是如果我們賦值的時候,你就可以發現,頁面卻是沒變的:

我們現在確實是都把它放到身上去了,但是它根本就沒法響應,那怎麼辦呢?

所以說,在這種情況下,我們並不是直接就把 obj 就給扔出去,我們需要再給它包一層。

還記得上篇博客是怎麼做的嗎?

所以這個跟我們前面的博客其實是一樣的,只不過其他地方的代碼稍微多了一點。

那麼在這裏,我們響應別的意義不大,這裏我只需要 set:

然後在 set 裏面,和之前一樣,我們需要做兩件事:

1,賦值。

2,渲染。

那麼這時候,我們再來試試:

可以看到,現在就變了。

而且,這個東西,對於我使用這個類來說,其實是沒什麼問題的:

依然還是很方便的。

然後,對於我去實現這個類來說,其實也還好。

比如像 construct 之類的這種操作,這個我們其實可以把它打包成一個通用的東西。

我們不需要這麼來寫,每次都放在這。

然後,以及它裏面_getRoot之類的:

其實我們可以通過公共的父級來做,而並不需要我自己來做這些事。

所以下篇博客,我們就來優化這些問題。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章