记录-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 解 ...
随机推荐
- NC16615 [NOIP2008]传纸条
题目链接 题目 题目描述 小渊和小轩是好朋友也是同班同学,他们在一起总有谈不完的话题.一次素质拓展活动中,班上同学安排做成一个m行n列的矩阵,而小渊和小轩被安排在矩阵对角线的两端,因此,他们就无法直接 ...
- Java核心技术卷1:基础知识(原书第10版)
本书为专业程序员解决实际问题而写,Java基础知识面覆盖很完整,可以帮助你深入了解Java语言和库.在卷I中,Horstmann主要强调基本语言概念和现代用户界面编程基础,深入介绍了从Java面向对象 ...
- test-02-java 单元测试框架 junit5 入门介绍
拓展阅读 junit5 系列 基于 junit5 实现 junitperf 源码分析 Auto generate mock data for java test.(便于 Java 测试自动生成对象信息 ...
- java 手写并发框架(二)异步转同步框架封装锁策略
序言 上一节我们学习了异步查询转同步的 7 种实现方式,今天我们就来学习一下,如何对其进行封装,使其成为一个更加便于使用的工具. 思维导图如下: 拓展阅读 java 手写并发框架(1)异步查询转同步的 ...
- SVG与foreignObject元素
SVG与foreignObject元素 可缩放矢量图形Scalable Vector Graphics - SVG基于XML标记语言,用于描述二维的矢量图形.作为一个基于文本的开放网络标准,SVG能够 ...
- springboot中前端ajax如何给controller提交数组参数?
说明 我有个需求,前端批量添加一堆商品明细.也就是说会有一个商品ID,然后一堆商品明细,多行. 如此一来,针对后端接口肯定是要以数组或列表方式接收这个商品明细数组了. 前端代码 关键地方在于以form ...
- VMWare“Could not get vmci driver version:句柄无效”的错误
这几天都不顺,从周一接手数据仓库的事,本来以为很简单,很快都能搞定,结果搞了一天没搞定,主要原因,自己觉得是系统底层搭建缺失个别库文件, 想换一个高一点版本的虚拟系统centos6.2结果又把虚拟机搞 ...
- win10下开启IIS部署网站
今天测试一个有关IIS的安全漏洞用了下win10下的IIS,记录一下,供网友参考. 1.启用IIS 依次点开: 控制面板-----程序----启用或关闭Windows功能 以下图片中打钩的地方全勾上. ...
- 使用JS实现博客搜索关键字高亮
说明 最近博客添加了搜索功能,有个需求是要针对搜索结果中搜索关键字需要高亮显示. 以便用户可以更快速的挑选自己中意的文章. 原理就是在渲染列表数据中给含有关键字的文本标签添加自定义class,渲染完毕 ...
- Failed to bind properties under ” to com.zaxxer.hikari.HikariDataSource
1.问题说明 今天配置spring boot多数据源,同时用到了oracle和postgresql,结果配置完毕后启动报这个错. 2.原因分析 忘记添加postgresql驱动了!!! 3.解决方案 ...
