Skip to content

只使用 vue 运行时 api 构造的 vue 项目

实际上,你完全可以不写任何一个 .vue 文件,只单独使用 vuejs 中的运行时渲染函数,去构建一个项目

vue 底层渲染函数

首先,我们先简单介绍一下他们

详见 https://cn.vuejs.org/api/render-function.html#h

当然,这篇文章并不是简单的 api 介绍,我们从 编译演练场例子中 获取他们在编译时候的使用到的地方

更多的底层的函数

实际上还有更多更底层的函数, 它们从 @vue/runtime-core@vue/runtime-dom 中导出

vue 编译器会把它们编译到 vue 文件的产物中去,我们一般情况下不会去调用它们。

这里简单列举一些

createVNode / createElementVNode / createBaseVNode / createElementBlock / createCommentVNode / createTextVNode

用于创建一个虚拟 DOM 节点 (VNode),它是 Vue 中的核心构建块。你可以用它来创建元素节点、组件节点、文本节点等。createVNode 是 Vue 的基础渲染 API。

之前上面的 h 函数的本质实际上就是 createVNode + isVNode 的二次封装,方便我们去使用的。

vue 编译器没有必要都去使用 h 函数这个二次封装,白白浪费性能,所以它编译的时候会转化成上面那些更加底层的方法。

renderList

v-for 循环渲染指令的产物,用于渲染一个列表或数组,将每个列表项作为一个单独的 VNode 创建,并进行渲染。

renderSlot

<slot></slot> 插槽的产物,用于渲染插槽,将插槽内容作为单独的 VNode 创建,并进行渲染。

Fragment

是一个容器,用于包裹多个 VNode 节点而不增加额外的 DOM 元素。Vue 3 引入了 Fragment,这样我们可以返回多个根元素,而不需要额外的包裹元素(如 div)。

这就是 vue3 <template> 里面无需像 vue2 那样,强制一个根节点的原因

openBlock

标记一个渲染块的开始,用于优化。Vue 在渲染过程中会把一些不常变化的元素分组成块,使用 openBlockcloseBlock 来标记这些块的开始和结束。它对渲染性能有优化作用。

toDisplayString

将一个表达式或值转换为字符串并进行转义,用于插值表达式 (例如 ) 中的文本显示。这是 Vue 内部处理插值显示的一部分。

vModelText

用于在 Vue 3 中创建文本输入框(<input><textarea>)的 v-model 双向绑定。它是 v-model 的低级实现,专门用于处理文本输入的绑定。

withCtx

用于传递上下文对象,通常用于组合式 API 中的功能,确保正确地绑定和传递 this 上下文。它通常用于函数式组件或者模板编译时,确保上下文能够在渲染函数中正确应用。

阅读源代码

我们来看一个不到任何 vue 编译功能的 vue 页面, 到底代码长什么样:

技术栈: vue3 + service worker + indexedDB + tailwindcss@4

源代码详见 apps/only-vue-runtime

线上地址: https://only-vue-runtime.netlify.app/

思考环节

vuejs 定义的 vue sfc 单文件中的 template,或者 jsx 等等,到底帮助我们少写了多少的代码?

Released under the CC BY-NC-SA 4.0 License.