导航:首页 > 源码编译 > vue3源码作者

vue3源码作者

发布时间:2024-09-22 12:11:36

‘壹’ Vue源码阅读【番外篇】:为什么Proxy需要搭配Reflect来实现响应式

前言

我们都知道vue3.x版本是通过Proxy来实现的,用以解决2.X的一些缺陷。

但是我最近通过看vue源代码发现它内部很多地方是Proxy、Reflect搭配一起使用的,例:

我们通过上面几张图可以看到get、set、deleteProperty、has、ownKeys都用了Reflect。

基于此,这就是我写这篇文章的缘由,那我们探索一下为什么要搭配这两使用。

Proxy和Reflect概念

Proxy:代理,可以通过代理对象完成对目标对象的拦截,并在拦截后进行过滤和改写等操作,支持的拦截操作共13种

Reflect:反射,它提供拦截JavaScript操作的方法。这些方法与?Proxy的方法一一对应,也是13种。

Proxy简单使用示例:const?person?=?{????name:?'张三',????get?nickName()?{????????return?`${this.name}是坏蛋`????}}const?personProxy?=?new?Proxy(person,?{????get(target,?key,?receiver)?{????????console.log('进来了吧')?????????return?target[key]????}})console.log(personProxy.nickName)//?先打印了:进来了吧//?然后打印了:张三是坏蛋

通过上面这个示例,我们发现他成功代理了,虽然我们没做什么处理。

不过get里面的receiver这个参数我们还没用到,receiver在这个时候表示代理对象(也就是personProxy)。

我们在get里面的returntarget[key],不能returnreceiver[key],否则会死循环。

我们再来个Proxy示例2:const?person?=?{????name:?'张三',????get?nickName()?{????????console.log(this)????????return?`${this.name}是坏蛋`????}}const?personProxy?=?new?Proxy(person,?{????get(target,?key,?receiver)?{????????return?target[key]????}})const?person2?=?{????name:?'李四'}Object.setPrototypeOf(person2,?personProxy)console.log(person2.nickName)

上面这个示例种的console.log(this)和console.log(person2.nickName)会打印上面呢?

我们希望的应该是person2这个对象和李四是坏蛋是吧,但实际上没有如期打印。

首先person2上面没有nickName这个属性,所以他会去personProxy上面找,然后返回了person上面的nickName属性,nickName中的this指向了person他自己。

所以console.log(this)打印出来的是person对象,console.log(person2.nickName)打印出来的是person中的name,也就是张三是坏蛋。

那我们怎么才能让他按照我们设想的那样打印李四是坏蛋?

我们来到第三个示例:const?person?=?{????name:?'张三',????get?nickName()?{????????console.log(this)????????return?`${this.name}是坏蛋`????}}const?personProxy?=?new?Proxy(person,?{????get(target,?key,?receiver)?{????????return?Reflect.get(target,?key,?receiver)????}})const?person2?=?{????name:?'李四'}Object.setPrototypeOf(person2,?personProxy)console.log(person.nickName)????????//?张三是坏蛋console.log(personProxy.nickName)???//?张三是坏蛋console.log(person2.nickName)???????//?李四是坏蛋/**???三次this打印的顺序如下:*???{?name:?'张三',?nickName:?[Getter]?}*???{?name:?'张三',?nickName:?[Getter]?}*???{?name:?'李四'?}*?*/

我们通过在get里面returnReflect.get(target,key,receiver)来实现按我们想要的那样打印出来。

我们给Reflect的get传递第三个参数(Proxy中的receiver),然后他就会修改调用时的this指向(也就是把指向person修改为:指向person2)。

我们引用阮老师中的Reflect代码片段来说明一下receiver,例:var?myObject?=?{??foo:?1,??bar:?2,??get?baz()?{????return?this.foo?+?this.bar;??},};var?myReceiverObject?=?{??foo:?4,??bar:?4,};Reflect.get(myObject,?'baz',?myReceiverObject)?//?8

如果name属性部署了读取函数(getter),则读取函数的this绑定receiver。

最后

最后我们引用vue官网的描述来理解一下:

使用Proxy的一个难点是?this?绑定。我们希望任何方法都绑定到这个Proxy,而不是目标对象,这样我们也可以拦截它们。值得庆幸的是,ES6引入了另一个名为?Reflect?的新特性,它允许我们以最小的代价消除了这个问题传送门

‘贰’ webpack作者评价vite

评价:Vite 是 vue 的作者尤雨溪在开发 vue3.0 的时候开发的一个 基于原生ES-Mole的前端构建工具。其本人在后来对 vue3 的宣传中对自己的新作品 Vite 赞不绝口,并表示自己 ”再也回不去 webpack 了“ 。

webpack缺点是缓慢的服务器启动

当冷启动开发服务器时,基于打包器的方式是在提供服务前去急切地抓取和构建你的整个应用。

vite改进

Vite 通过在一开始将应用中的模块区分为依赖和源码两类,改进了开发服务器启动时间。

依赖大多为纯JavaScript并在开发时不会变动。一些较大的依赖(例如有上百个模块的组件库)处理的代价也很高。依赖也通常会以某些方式(例如 ESM 或者 CommonJS)被拆分到大量小模块中。

Vite 将会使用 esbuild 预构建依赖。Esbuild 使用 Go 编写,并且比以 JavaScript 编写的打包器预构建依赖快10-100倍。

源码通常包含一些并非直接是 JavaScript 的文件,需要转换(例如 JSX,CSS 或者 Vue/Svelte 组件),时常会被编辑。同时,并不是所有的源码都需要同时被加载。(例如基于路由拆分的代码模块)。

Vite以原生ESM方式服务源码。这实际上是让浏览器接管了打包程序的部分工作:Vite 只需要在浏览器请求源码时进行转换并按需提供源码。根据情景动态导入的代码,即只在当前屏幕上实际使用时才会被处理。

webpack: 分析依赖=> 编译打包=> 交给本地服务器进行渲染。首先分析各个模块之间的依赖,然后进行打包,在启动webpack-dev-server,请求服务器时,直接显示打包结果。

webpack打包之后存在的问题:随着模块的增多,会造成打出的 bundle 体积过大,进而会造成热更新速度明显拖慢。

vite: 启动服务器=> 请求模块时按需动态编译显示。是先启动开发服务器,请求某个模块时再对该模块进行实时编译,因为现代游览器本身支持ES-Mole,所以会自动向依赖的Mole发出请求。

所以vite就将开发环境下的模块文件作为浏览器的执行文件,而不是像webpack进行打包后交给本地服务器。

分析了webpack和vite的打包方式后,也就明白了为什么vite比webpack打包快,因为它在启动的时候不需要打包,所以不用分析模块与模块之间的依赖关系,不用进行编译。这种方式就类似于我们在使用某个UI框架的时候,可以对其进行按需加载。

热更新方面,效率更高。当改动了某个模块的时候,也只用让浏览器重新请求该模块,不需要像webpack那样将模块以及模块依赖的模块全部编译一次。

阅读全文

与vue3源码作者相关的资料

热点内容
支付宝账单文件如何解压 浏览:857
查看内核版本命令 浏览:954
w10加密盘驱动锁死怎么办 浏览:944
全新云服务器价格对比 浏览:383
python为什么去除了switch语句 浏览:54
二进制7到8的算法 浏览:807
服务器机柜叫什么名字 浏览:347
vue3源码作者 浏览:830
app右下角标怎么关 浏览:832
怎么对一个盘加密码 浏览:670
练习sql用什么样的服务器 浏览:980
asp与php对比 浏览:645
php模除 浏览:254
android上传图片方式 浏览:886
华为视频会议服务器如何连接 浏览:224
phpfpm并发数 浏览:925
云服务器哪里看 浏览:245
戴尔emc服务器led怎么拔出 浏览:794
程序员霸王 浏览:371
文件夹重合如何分开 浏览:163