记录-Vue.js模板编译过程揭秘:从模板字符串到渲染函数
这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助
Vue.js是一个基于组件化和响应式数据流的前端框架。当我们在Vue中编写模板代码时,它会被Vue编译器处理并转换为可被浏览器解析的JavaScript代码。Vue中的模板实际上是HTML标记和Vue指令的组合,它们会被Vue编译器处理并转化为一个JavaScript渲染函数。
Vue中的模板编译分为两个阶段:
1.解析阶段
在这个阶段,Vue将模板字符串解析为AST(抽象语法树)的结构。解析器会扫描模板字符串,识别出其中的HTML标签、属性、表达式等内容,然后构建成一个抽象语法树。这个过程中也会对表达式进行解析和优化,以生成更高效的渲染函数。
例如,下面是一个简单的Vue模板:
<div>
<h1>{{ title }}</h1>
<ul>
<li v-for="item in items">{{ item }}</li>
</ul>
</div>
在解析阶段,Vue将这个模板解析为AST的结构:
{
type: 'element',
tag: 'div',
attrsList: [],
children: [
{
type: 'element',
tag: 'h1',
attrsList: [],
children: [{ type: 'expression', expression: 'title' }]
},
{
type: 'element',
tag: 'ul',
attrsList: [],
children: [
{
type: 'element',
tag: 'li',
attrsList: [{ name: 'v-for', value: 'item in items' }],
children: [{ type: 'expression', expression: 'item' }]
}
]
}
]
}
2.代码生成阶段
在这个阶段,Vue将AST转换为渲染函数。渲染函数是一个JavaScript函数,它接收一个上下文对象作为参数,并返回一个VNode(虚拟节点)对象,表示要渲染的DOM树结构。在渲染函数中,Vue会将模板中的HTML标签转换为createElement
函数调用,将指令和表达式转换为相应的JavaScript代码。
例如,对于上面的模板,生成的渲染函数大致如下:
function render(_ctx, _cache) {
return _openBlock(), _createBlock("div", null, [
_createVNode("h1", null, _toDisplayString(_ctx.title), 1 /* TEXT */),
_createVNode("ul", null, [
(_cache[item] || (_cache[item] = _withDirectives((_openBlock(), _createBlock("li", {
key: item
}, _toDisplayString(item), 1 /* TEXT */)), [[_directive_resolveModel, _ctx.items, item]])))
])
])
}
在上面的渲染函数中,我们可以看到通过调用Vue提供的_createVNode
函数和_createBlock
函数来创建虚拟节点,并使用_toDisplayString
函数来将表达式的值转换为字符串。同时,在循环中使用了_cache
对象来缓存已渲染的VNode,以提高渲染性能。
总的来说,Vue的模板编译过程将模板字符串转换为一个JavaScript函数,该函数接收一个上下文对象作为参数,并返回一个VNode对象,表示要渲染的DOM树结构。这个过程中,Vue将模板中的HTML标记和指令转换为JavaScript函数调用,同时对表达式进行解析和优化,以生成更高效的渲染函数。
举一个更具体的例子,考虑下面这个Vue模板:
<template>
<div class="wrapper">
<h1>{{ message }}</h1>
<ul>
<li v-for="item in items">{{ item }}</li>
</ul>
</div>
</template>
在编译过程中,Vue将模板字符串解析为AST的结构,如下所示:
{
type: 'element',
tag: 'div',
attrsList: [{ name: 'class', value: 'wrapper' }],
children: [
{
type: 'element',
tag: 'h1',
attrsList: [],
children: [{ type: 'expression', expression: 'message' }]
},
{
type: 'element',
tag: 'ul',
attrsList: [],
children: [
{
type: 'element',
tag: 'li',
attrsList: [{ name: 'v-for', value: 'item in items' }],
children: [{ type: 'expression', expression: 'item' }]
}
]
}
]
}
然后,Vue将AST转换为一个渲染函数,如下所示:
function render(_ctx, _cache) {
return _openBlock(), _createBlock("div", { class: "wrapper" }, [
_createVNode("h1", null, _toDisplayString(_ctx.message), 1 /* TEXT */),
_createVNode("ul", null, [
(_cache[item] || (_cache[item] = _withDirectives((_openBlock(), _createBlock("li", {
key: item
}, _toDisplayString(item), 1 /* TEXT */)), [[_directive_resolveModel, _ctx.items, item]])))
])
])
}
_createVNode
和_createBlock
函数的调用,将指令和表达式转换为相应的JavaScript代码,并使用_toDisplayString
函数将表达式的值转换为字符串。最终生成的渲染函数会被Vue用来渲染组件的实例。本文转载于:
https://juejin.cn/post/7221354195914326073
如果对您有所帮助,欢迎您点个关注,我会定时更新技术文档,大家一起讨论学习,一起进步。
记录-Vue.js模板编译过程揭秘:从模板字符串到渲染函数的更多相关文章
- JS预编译过程
GO和AO 变量的预编译 实例1 console.log(a); var a=1; console.log(a); 实际编译过程: 将a存入预编译对象中,赋值为undefined: 真正的赋值语句当程 ...
- smarty 模板编译和变量调节器 模板引入
<?php require './smarty/Smarty.class.php'; $sm = new Smarty; //$sm->force_compile = true; $sm- ...
- Vue 源码解读(10)—— 编译器 之 生成渲染函数
前言 这篇文章是 Vue 编译器的最后一部分,前两部分分别是:Vue 源码解读(8)-- 编译器 之 解析.Vue 源码解读(9)-- 编译器 之 优化. 从 HTML 模版字符串开始,解析所有标签以 ...
- 解决vue.js在编写过程中出现空格不规范报错的情况
找到build文件夹下面的webpack.base.conf.js文件. 然后打开该文件,找到图下这段代码,把他注释掉. 注释掉之后,再进行子页面等编写的时候,空格不规范的情况下也不会再报错啦.因为这 ...
- vscode实现vue.js项目的过程
https://blog.csdn.net/weixin_37567150/article/details/81291433 https://blog.csdn.net/ywl570717586/ar ...
- vue原理:diff、模板编译、渲染过程等
一.虚拟DOM: 因为DOM操作非常消耗性能,在操作DOM时,会出现DOM的回流(Reflow:元素大小或者位置发生改变)与重绘(元素样式的改变)使DOM重新渲染. 现在的框架Vue和React很少直 ...
- vue.js+webpack在一个简单实例中的使用过程demo
这里主要记录vue.js+webpack在一个简单实例中的使用过程 说明:本次搭建基于Win 7平台 Node.js 安装官网提供了支持多种平台的的LTS版本下载,我们根据需要来进行下载安装.对于Wi ...
- Vue.js——60分钟browserify项目模板快速入门
概述 在之前的一系列vue.js文章,我们都是用传统模式引用vue.js以及其他的js文件的,这在开发时会产生一些问题. 首先,这限定了我们的开发模式是基于页面的,而不是基于组件的,组件的所有代码都直 ...
- Vue.js——60分钟browserify项目模板快速入门
概述 在之前的一系列vue.js文章,我们都是用传统模式引用vue.js以及其他的js文件的,这在开发时会产生一些问题. 首先,这限定了我们的开发模式是基于页面的,而不是基于组件的,组件的所有代码都直 ...
- Vue.js系列之三模板语法
Vue.js 使用了基于 HTML 的模板语法,允许开发者声明式地将 DOM 绑定至底层 Vue 实例的数据.所有 Vue.js 的模板都是合法的 HTML ,所以能被遵循规范的浏览器和 HTML 解 ...
随机推荐
- 【译】.NET 8 网络改进(一)
原文 | Máňa,Natalia Kondratyeva 翻译 | 郑子铭 随着新的 .NET 版本的发布,发布有关网络空间中新的有趣变化的博客文章已成为一种传统.今年,我们希望引入 HTTP 空间 ...
- Pandas数据合并
目录 1) 在单个键上进行合并操作 2) 在多个键上进行合并操作 使用how参数合并 1) left join 2) right join 3) outer join(并集) 4) inner joi ...
- NC23482 小A的最短路
题目链接 题目 题目描述 小A这次来到一个景区去旅游,景区里面有N个景点,景点之间有N-1条路径.小A从当前的一个景点移动到下一个景点需要消耗一点的体力值.但是景区里面有两个景点比较特殊,它们之间是可 ...
- 【Unity3D】顶点和片元着色器
1 前言 上文介绍了渲染管线.固定管线着色器和表面着色器,如下: 渲染管线 固定管线着色器一 固定管线着色器二 表面着色器 固定管线着色器通过命令方式实现光照和贴图等效果,表面着色器通过给 S ...
- win32 - 内存映射(CreateFileMapping)
目标:创建一个app,使用CreateToolhelp32Snapshot扫描所有的进程,并将进程的pid和exe名字映射到内存中,再在另一个app中使用OpenFileMapping打开该映射读取相 ...
- java基础集合类之ArrayList---01
集合类之ArrayList ArrayList<E>: 1.可调整大小的数组实现 2.<E>:是一种特殊的数据类型,泛型 3.在出现E的地方我们使用引用数据类型替换即可:Arr ...
- fastdfs存储和下载过程
- Vue3学习(十九) - TreeSelect 树选择
写在前面 我知道自己现在的状态很不好,以为放个假能好好放松下心情,结果昨晚做梦还在工作,调试代码,和领导汇报工作. 天呐,明明是在放假,可大脑还在考虑工作的事,我的天那,这是怎么了? Vue页面参数传 ...
- GPS坐标系转换 go golang 版本
GPS坐标系转换 坐标系 解释 WGS84坐标系 地球坐标系,国际通用坐标系 GCJ02坐标系 火星坐标系,WGS84坐标系加密后的坐标系:Google国内地图.高德.腾讯地图 使用 BD09坐标系 ...
- 【算法day4】堆结构、堆排序、比较器以及桶排
堆与堆结构(优先级队列结构) 知识点: 堆结构就是用数组实现的完全二叉树结构 完全二叉树中如果每棵子树的最大值都在顶部就是大根堆 完全二叉树中如果每棵子树的最小值都在顶部就是小根堆 堆结构的heapl ...