Vue3框架设计思想
前言
工具的出现是为了提升效率。框架的直接用户是开发人员,间接用户是所有人。所以好的框架应该让用户有好的开发体验,能通过框架产生好的产物。
一、编程范式
从编程范式(指的是编程风格,是对代码编写方式的一种抽象)上来看,视图层框架通常分为命令式
和声明式
,它们各有优缺点。作为框架设计者,应该对两种范式都有足够的认知,这样才能做出正确的选择,甚至想办法汲取两者的优点并将其捏合。
1.命令式编程
// `jQuery` 就是典型的命令式框架
$('#app') // 获取 div
.text('hello world') // 设置文本内容
.on('click', () => { alert('ok') }) // 绑定点击事件
关注过程
。代码本身描述的是“做事的过程”。- 因为知道要做什么和怎么做,所以命令式代码可以做到
极致的性能优化
。 - 但是用户要
承受巨大的心智负担
,知道自己每一次操作的最优解和阅读别人的代码。
2.声明式编程
关注结果
。不关心完成功能的详细逻辑与步骤。- 可以
减轻用户的心智负担
,不需要考虑实现细节,套模板就行。 - 代码方便阅读,
可维护性好
。
3.性能与可维护性的权衡
由以上分析可知,声明式代码的性能不优于命令式代码的性能
。但是,声明式代码比命令式代码可维护性要好
。二者要怎么选呢?此时,体现了性能与可维护性的权衡。框架设计者要做的就是:在保持可维护性的同时让性能损失最小化
。权衡之后的方案就是:Vue封装命令式的逻辑,对外暴露出声明式的接口
。
二、运行时和编译时
当设计一个框架的时候,我们有三种选择:纯运行时的
、运行时 + 编译时的
或纯编译时的
。这需要你根据目标框架的特征,以及对框架的期望,做出合适的决策。
1.运行时
提供一个 Render
函数,用户可以为该函数提供一个树型结构的数据对象,然后 Render
函数会根据该对象递归地将数据渲染成 DOM
元素。
- 由于它没有编译的过程,因此我们没办法分析用户提供的内容。
- 因为不存在编译器,所以需要用户提供一个复杂的
JS
对象。
2.编译时
编写一个 Compiler
程序,把 HTML
字符串直接编译成命令式代码。
- 由于不需要任何运行时,而是直接编译成可执行的
JS
代码,因此性能可能会更好。 - 但是这种做法有损灵活性,即用户提供的内容必须编译后才能用。
3.运行时 + 编译时
由以上分析可知,编译时 + 运行时
,可以在保持灵活性的基础上,还能够通过编译手段分析用户提供的内容,从而进一步提升更新性能。Vue
使用这种策略,达到一种平衡。
4.Vue的编译时 + 运行时
Vue
单文件组件中template
模块中的html
标签并不是真实的html
节点。因为对于浏览器,它不能识别v-if、v-bind
等属性。
- 编译时可以把
html
接口的节点,编译成render
函数。compile(
编译器):把template
中的html
编译成render
函数。再利用运行时通过render
函数挂载对应的DOM
。
- 运行时可以利用
render
函数把vnode
渲染成真实的dom
节点。render
函数:用于编程式地创建组件虚拟DOM
树。
三、总结
从编程范式和编译时/运行时两个方面去了解Vue
的设计思想。封装命令式的逻辑,对外暴露出声明式的接口;使用编译时 + 运行时策略
。框架的设计是一个不断取舍的过程,在保持可维护性的同时让性能损失最小化,在保持灵活性的基础上提升性能
。
附录
- 书籍:霍春阳.Vue.js设计与实现
转载自:https://juejin.cn/post/7240697872161161276