Vue 模板的本质
介绍
接下来的内容,可以让你对 vue 对模板彻彻底底的毕业,一旦毕业,你就再也不需要去学习它了。
定义
模板的本质就是一个语法糖。实际上在运行时它是没有的,运行的而是另外的东西。
函数渲染
在 vue3 中我们可以直接在 setup 函数中返回一个渲染函数,渲染函数的作用就是在渲染,那么什么是渲染呢?就是封装一些虚拟节点,再去递归遍历这个节点,通过创建元素形成 DOM 树。
vue3 中使用 h 函数来创建虚拟节点。
<script lang="ts">
import { h } from 'vue'
export default {
setup() {
return () => {
const list = []
for (let i = 0; i < 100; i++) {
list.push(h('li', null, i))
}
return h('ul', null, list)
}
}
}
</script>
也就是在浏览器里面真正运行的就是这个渲染函数,因为它描述了这个组件的渲染过程,渲染的结果就是页面的结构。而模板就是这一切的语法糖而已。
因为我们自己手写渲染函数比较麻烦,所以就有了模板一样的语法糖,像是 html 一样,就会比较高效快捷。
像是这样:
<template>
<ul>
<li v-for="i in 100">{{ i }}</li>
</ul>
</template>
模板编译
既然模板只是一个语法糖,那么它肯定是有一个时间节点将语法糖转换为 render 函数,那么这个变化的过程,就是常说的模板编译,说到编译,就会有两个问题:
是什么时候做的呢?是谁来做的呢?
谁来做的呢?我门都知道,vue 中有很多模块,其中就有编译器模块,叫 compiler
,在 vue 的 packages 中可以看到 compiler-core
、compiler-dom
、compiler-sfc
、compiler-ssr
等编译模块。
什么时候做呢?这个时候一般分为两种情况,主要涉及到一些效率和性能问题。
第一种是运行时。也就是代码在运行到浏览器的时候再编译,叫运行编译,通常使用传统工程开发的时候,使用 script 引入 vue 包的方式,像是这样:
<script src="./vue.js"></script>
<script>
new Vue({
template: `<div>123</div>`
})
</script>
这样的做法缺陷也非常明显,第一是编译模块要打包进去,引入要在浏览器阶段编译,第二点就是体积大。
第二种就是编译时编译,为什么推荐使用像 vite 这样的开发框架,当然原因有很多,其中比较重要的是,模板编译这一步,在编译阶段就已经完成了,我门在 *.vue
中写的内容,其实就是一段字符串,通过打包、模板编译将它变化为 render 函数,真正在浏览器中运行的就直接说 render 函数了,而不需要在浏览器阶段去编译了,所以编译模块也不需要打包,也可以大幅度提高运行效率。
结论
所以我门在模板中写的什么 v-for
、v-if
指令啊,最终运行的时候就都没有了。运行的就是一个循环编译、三运运算符等一些普通的 js 代码。