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之类的:

其实我们可以通过公共的父级来做,而并不需要我自己来做这些事。

所以下篇博客,我们就来优化这些问题。

 

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