一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第14天,点击查看活动详情。
本题难度:⭐ ⭐
本题类型:综合题、开放问题
答:简单来说,运行时是指一段代码,直接扔进浏览器里能运行,编译时是指一段代码不能直接在浏览器里跑,需要先经过编译器编译,再放到浏览器里才能运行。
运行时
比如:提供一个 render 函数,接收两个参数,一个是具有一定规范的树型结构的数据对象,一个是要挂载的节点。
开发者把树型结构的数据对象传入 render 函数,然后 render 函数根据改对象递归地将数据渲染成 DOM 元素。
这个树型结构须按照一定的规范,形状如下:
const node = {
tag: 'div', // tag代表标签名称
children: [ // children可以是一个数组,代表子节点
{
tag: 'h1',
children: 'hello' // children也可以是一段文本,代表文本子节点
}
]
}
复制代码
render 函数的实现如下:
function render (node, root) {
const el = document.createElement(node.tag)
if (typeof node.children === 'string') {
const text = document.createTextNode(node.children)
el.appendChild(text)
}
if (Array.isArray(node.children)) {
node.children.forEach(child => render(child, el)) // 递归地处理节点的渲染
}
root.appendChild(el)
}
复制代码
执行 render 函数,就可以生成页面元素,如下图:
这种使用纯 JS 的方式生成页面内容就是运行时框架,很显然,在开发者层面,通过这种方式书写代码一定会非常痛苦。
所以在 Vue 里面,我们写的不是类似上文的代码,而是写 template 模板。
编译时
比如,下面这段代码,浏览器里不能直接跑,需要先编译成 JS ,才能在浏览器里运行。
<template>
<div>
<h1>hello</h1>
</div>
</template>
复制代码
假设上面的 html 代码,直接编译成命令式的代码,就是编译时代码,如下所示:
const div = document.createElement('div')
const h1 = document.createElement('h1')
h1.innerText = 'hello'
div.appendChild(h1)
document.body.appendChild(div)
复制代码
开发者只提供 html 模板代码,在框架内部分析开发者提供的代码,编译成命令式的代码,再渲染到页面上。
但是很显然,Vue 不是这么做的,我们在这个 在线网址 里去测试一下:
<template>
<div>
<h1>hello</h1>
</div>
</template>
复制代码
这段 html 代码在 Vue 内部被编译成下面这段代码。
import { createElementVNode as _createElementVNode, openBlock as _openBlock, createElementBlock as _createElementBlock } from "vue"
export function render(_ctx, _cache, $props, $setup, $data, $options) {
return (_openBlock(), _createElementBlock("template", null, [
_createElementVNode("div", null, [
_createElementVNode("h1", null, "hello")
])
]))
}
复制代码
这段编译出来的代码,引入了一些乱七八糟的函数,传了一些乱七八糟的参数,很显然,这样的代码不是单纯的操作 DOM 的原生 JS,还包含了创建 VNode 、diff等操作。
由此,我们可以得出结论,Vue 是一个运行时 + 编译时的框架,在编译时把浏览器看不懂的代码转化为 JS 代码,在运行时创建虚拟 DOM,做 diff 对比,更新真实 DOM 等等操作。
举一些实例,比如 jQuery,就是一个运行时框架;Vue 或者 React,就比较折中,是运行时 + 编译时框架;而 Svelte ,就是一个编译时框架。
结尾
阿林水平有限,文中如果有错误或表达不当的地方,非常欢迎在评论区指出,感谢~
如果我的文章对你有帮助,你的就是对我的最大支持^_^
你也可以关注《前端每日一问》这个专栏,防止失联哦~
我是阿林,输出洞见技术,再会!
本文参考:Vue.js设计与实现
上一篇:
「前端每日一问(50)」虚拟 DOM 和原生 JS 究竟谁性能更好?
下一篇: