所以vueconf
今天在线,我显然无法理解有多少客人分享了一些基本原则;回想起来,从vue2.x
开始,我已经使用vue
两年多了,但对很多底层实现机制理解还不是很深。最近我在一些项目中使用vue3 + vite
进行开发。我发现vue3和vite
很多地方都是革命性的变化。我对它们很感兴趣,所以我给自己挖了这个大坑。我从研究vue3
的源代码开始。一步步爬上这座山。
为什么?
为什么要学习vue.js
源代码?
- 有助于提高 JavaScript 技能
- 提高工作效率,形成学习与成长的良性循环
- 学习优秀源码的经验,站在巨人的肩膀上看世界
- 提高解读源代码的能力
为什么很少有人愿意看源码?
- 因为学习源码非常繁琐,不像开发项目可以快速得到反馈并立即看到结果
- 学习源码比开发项目更加抽象,难以理解。很多人学习后就放弃了。
- 还有很多人想学却学不到
接下来我们看一下vue 3.0中所做的优化:
源码优化
- 库结构调整
主要体现在使用monorepo
和typescript
来管理和开发源代码。这样做的目的是为了提高自身代码的可维护性;




- 放弃
Flow
以使用typescript
重写Vue
源代码。
性能优化
- 删除了一些不受欢迎的功能:过滤器、内联模板等。
- 引入tree-shaking技术,优化源代码大小
依靠ES2015模块语法的静态结构(即导入和导出),通过编译阶段的静态分析,找到并标记未导入的模块。
如果项目中不引入Transition
、keepAlive
等组件,其对应的代码将不会被打包,间接达到了减少项目引入的keepAlive
封装体积的目的。
数据劫持优化
vue 2.x 数据劫持缺陷
- 由于
getter
和setter
被Object.defineProperty
API劫持,需要提前知道拦截到的key
是什么,因此无法检测到添加和删除属性。$set
和$delete
旨在改善,但会增加额外的精神压力。 - 对于嵌套层次较深的对象,必须逐层递归遍历对象,这会影响性能。
vue 3.x 使用代理直接捕获整个对象的变化。 getter 响应式。
的好处是,真正访问的内部对象变得响应式,而不是无意识的递归,这无疑大大提高了性能。
编译优化
先看看Vue的编译过程
在 vue 2.x 中,当我们有这样的代码块时:
<div>
<p>hello</p>
<p>I</p>
<p>am</p>
<p>{{yourName}}</p>
<p>!</p>
</div>
可以看到,只有第四个p-tag的值是动态的,但是vue 2.x进行diff时,它会和父div一步步不同,一步步变化,不管我们的值是否是动态的还是静态的,这无疑会造成很大的性能浪费。
Vue3在编译阶段通过对静态模板的分析,编译生成一棵块树,这是一个基于动态节点指令雕刻出模板的嵌套块。每个块内部的节点结构是固定的,每个块只需要使用一个Array来跟踪它包含的动态节点。使用块树,vue.js 将 vnode 更新性能从与整体模板大小 相关到与动态内容数量 相关。
此外,编译阶段还包括槽编译优化和事件监听函数缓存优化,以及运行时重写diff算法。
语法优化:Composition API
vue 1.x 和 vue 2.x 编写组件基本上就是编写一个“包含描述组件的选项的对象”,一般称为 Option API
,其设计符合 method
, ,,,props
等各种选项进行了分类,其书写习惯与我们最初使用的插件(如轮播)时给出的配置参数相对应。当元件比较小时,这种分类一目了然;但在大型组件中,一个组件可能有多个逻辑关注点。如果要改某个逻辑点的代码,就得不断地上下切换单个文件并查找,非常痛苦。虽然后来提出了mixins的方案来封装和分割业务逻辑,但是mixins本身还是存在很多问题,比如相同属性和方法字段的覆盖策略的优先级以及mixins中的数据字段更改为其他mixin或main 文件造成的副作用等;
vue 3.0 提供了一个新的 API:Composition API,当然它也是一个独立的可安装模块@vue/composition-api,它将逻辑关注点的所有相关代码放在一个函数中,这样当你需要更改一个函数时,您不需要跳转各个文件。很大程度上还可以实现一些逻辑上的复用。
两个API在逻辑较多时的颜色对比,单个文件的呈现:
组合 API 函数
- 除了逻辑复用的好处之外,还会有更好的类型支持;
- 因为它本质上是一个函数,所以在调用函数时自然会推断出所有类型。我不想将其用于选项 api 中的所有内容;
- 此外,Composition API 还优化了 tree shake,代码更容易压缩;
- 当然,Composition API只是一种新的增强编写方式,在vue3中并不是强制的,如果你的代码足够简单,可以继续使用SFC Option API进行开发
RFC的引入:让各个版本的变更更加可控
- 维护人员通过 RFC 对每个版本进行更改来确定其更改
- 用户还可以阅读 RFC 以了解每个功能采用或放弃的来龙去脉
终于
由于vue 3.0是使用ES2015语法开发的,所以一些API如Proxy没有polyfills,这意味着官方必须发布一个单独的IE11兼容版本来支持IE11,但是我从最新的vueconf
昨天,有达本人表示,短期内不会对IE11进行任何兼容性改动,而近期微软官方也表示IE11即将结束维护,更加看好Edge浏览器。
对于目前的vue 2.0,官方计划是继续维护18个月。今年发布了最后一个主要版本 vue 2.7,然后只有 bug 修复版本。
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。