刨析Vue3.0系列(二)-源码篇

4 篇文章 0 订阅
4 篇文章 0 订阅

上节内容主要介绍了一下新的Vue所依赖的响应式数据方案Proxy所带来的性能提升,其实劫持了整个对象除了提升了性能之外,更重要的是对于实现方案的优化,由于对象本身的功能限制,Object.defineProperty并支持Map\Set,对于习惯使用这两种对象的同学们来说,这不得不说是一大遗憾,只能选用数组执行,但对数组基于下标的修改和对于.length变化的监测又不够友好。而使用Proxy显然是解决了这些问题。

本节内容我们继续探索一下Vue3对于性能方面的优化所做的努力-》重写虚拟DOM:

我们知道,Vue采用了virtual-dom,其核心的diff算法让我们不需要再去操心dom渲染问题,但virtual-dom是目前最快的虚拟dom实现方案吗?

答案是否定的,浩瀚的网络中,总有对单一目标执着的猿,执着的向着‘更快’前进:

通过JS Web框架基准测试,当前虚拟dom实现方案的性能排序如下

在这里插入图片描述

Vue自然不可能掘根式的将自己的virtual-dom给替换成Inferno,但其中的一些优化技巧,却是可以学习的。这次改造,使得Vue的整体性能提升了一倍,最直接的体现是应用的启动时间将缩短一半。

同时,新的虚拟dom实现带来的性能提升,使得Vue可以执行一些更加高效的编译耗时优化,静态树的提升、静态属性的提升,以及为运行时提供来自编译器的提示等。

关于这一块,我们并不需要深入的了解其原理,因为这一块的升级是润物细无声的,既没有新的api,也没有新的功能点使用,但确实是性能得以提升的核心,在这里我们不做深刻的讨论对比Vue与inferno的优劣。感兴趣的同学可以自己深入了解一下。

https://infernojs.org/benchmarks

好的,关于3.0的简述到此为止,接下来,我们开始读一下已经放出来的Vue3.0的源码,咱们从源码,触控一下3.0的灵魂

在此之前,你需要了解一下:

Proxy
Symbol
Map
Set

这些在3.0中大量使用到的对象,然后最好具有TypeScript的相关知识,这点很重要,即将发布的3.0将全面支持TypeScript的语法标准,毕竟强类型的开发语言可以有效降低程序的类型问题。

放一下git传送们:https://github.com/vuejs/vue-next

我们可以先看一下3.0的包文件夹,通过阅读他们的Readme文档,我们可以看出自上往下分别是:运行时构建的入口和其独立构建版本,reactivity,运行时的代码,针对浏览器的runtime代码,为了测试而些的轻量级runtime,服务端渲染,共享模块,模板编译输出的实时资源管理器和Vue的模型。

在这里插入图片描述

我们可以逐个解读一下这些模块的功能。

先从看起来就比较奇怪的reactivity开始吧~!

reactivity是响应式系统的数据观测核心代码,打开Readme,文档中清晰写明了”这个包被内联到面向用户的渲染器的构件中,但也可以作为独立使用的包发布”还有一些公开的api,我们可以去index.ts中查看。

然后我们可以从Vue3入门到放弃了~本篇文章到此结束,感谢各位的收看。

在这里插入图片描述

开玩笑,开玩笑,各位请先别动手,咱们继续往下分析

在这里插入图片描述

入口文件列出了所有对外的api模块与依赖内容,目前我们还不知道各个模块的功能与含义,咱们继续拆分即可。

其中ref与reactive是源码中的入口和核心模块,响应式数据即是通过这两个方法创建的,我们必须先理解这两个部分,才能理解整个reactivity。

在这里插入图片描述

这里是ref.ts中的内容,我们可以看到,其中主要有ref、isRef、toRefs、等方法组成,我们从上往下看,Ref的数据结构由两部分组成,用_isRef做类型的标识,用value进行数据存储,通过最下面的解构方法,我们可以看出,对于每一种类型的嵌套,都进行了解析,不过需要注意的是,在第66行的部位,明确的表示了不能被解套的复杂数据类型。

继续往下分析,ref函数具体的实现了Ref类型的数据,在ref函数中,当遇到了非Ref类型的数据的情况下,会生成了一个数据结构,由_isRef,get,set组成,最后会返回一个Ref类型的数据,在这个里面,调用了一些其他模块的方法,我们可以在读到这一块的源码的时候,再着重的去了解track和trigger,看这两个暴露出的方法的目的是什么。

有的同学可能看到这里会有些疑惑,你之前一直在提,一直在强调的Pxoxy呢!什么性能提高多少多少!为什么一点也没有看到!?你是不是在匡人?

在这里插入图片描述

这个,当然并不是了,不要着急,我们马上就要分析到了这一块了

实际上,创作团队在ref函数中,创建了一个对象,也就是刚才的那个数据结构,然后将这我们的原始数据存在了ref的value中,然后再把引用返回给了使用者,由于这个对象是我们自己创造出来的,就完全不需要proxy再做一个代理,我们直接劫持这个value的get/set就可以了。但这样写还有一个缺点,就是只能保持基本数据类型实现响应式,并没有实现对对象的解构,于是创作团建又创建了一个toRefs函数解决这个问题,在这个函数中,通过遍历对象所有的key,调用了toProxyRef方法,将其所有的值都转化为Ref的数据。这样就保证了所有的数据都具有了响应式数据的引用。作者在想,如果往toRef中注入了一个Ref对象会返回什么呢?

好的,读到了这里,ref中的内容我们已经读的差不多了,下一章我们看一下核心的reaactive,看看模块同名文件,要实现的是什么。

才疏学浅,可能分析的有所瑕疵,感谢各位老师的指正,最后,作者在这里恭祝大家节日快乐了。来都来了,都看到这了,你不点个赞再走吗?
在这里插入图片描述

参考链接

https://juejin.im/post/5bb719b9f265da0ab915dbdd

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vue3.0中的组件高级功能包括保持动态组件状态和引用DOM元素。 保持动态组件状态的方法是使用Vue内置的<keep-alive>组件。通过将动态组件包裹在<keep-alive>标签中,可以在切换动态组件时保持组件的状态。例如: ```html <keep-alive> <component :is="comName"></component> </keep-alive> ``` 在这个例子中,comName是一个data属性,用于指定当前要渲染的组件的名称。通过在<component>标签中使用:is属性,可以动态地指定要渲染的组件。 引用DOM元素的方法是使用ref属性。通过给DOM元素添加ref属性,可以在组件中通过$refs属性获取对DOM元素的引用。例如: ```html <template> <h3>MyRef组件</h3> <button @click="getRef">获取$refs引用</button> </template> <script> export default { methods: { getRef() { console.log(this.$refs) // $refs指向一个空对象,需要在DOM元素上添加ref属性 } } } </script> ``` 在这个例子中,点击按钮后,调用getRef方法可以在控制台上输出当前组件实例对象this。通过this.$refs可以访问到DOM元素的引用。 以上就是Vue3.0中组件高级功能的两个示例,分别是保持动态组件状态和引用DOM元素。希望能对你有所帮助。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [Vue3.0----组件高级【下】(第五章)](https://blog.csdn.net/QQ675396947/article/details/127486948)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值