记录-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 解 ...
随机推荐
- UUID算法:独一无二的标识符解决方案
引言 在分布式系统和大数据环境下,唯一标识符的生成和管理是一项关键任务.UUID(Universally Unique Identifier)算法应运而生,成为了解决重复数据和标识符冲突的有效工具.本 ...
- JS leetcode 最长公共前缀 题解分析
壹 ❀ 引 今天做的又是一道让我沮丧的题,思路有,但是代码逻辑最后还是没能正确理出来,题名为最长公共前缀,题目如下: 编写一个函数来查找字符串数组中的最长公共前缀. 如果不存在公共前缀,返回空字符串 ...
- sensitive word 敏感词(脏词) 如何忽略无意义的字符?达到更好的过滤效果?
忽略字符 说明 我们的敏感词一般都是比较连续的,比如 傻帽 那就有大聪明发现,可以在中间加一些字符,比如[傻!@#$帽]跳过检测,但是骂人等攻击力不减. 那么,如何应对这些类似的场景呢? 我们可以指定 ...
- Spring的接口集合注入功能
Spring的接口集合注入功能 对于Spring中已经注入的bean, 可以使用Autowired, 通过Map<String, BeanInterface>或List<BeanIn ...
- 系统环境变量中 HTTPS_PROXY 的误区
前段时间在测试一个连麦 demo,demo 简要说可以在内网环境中运行时,输入频道号就可以模拟连麦 但是在加入连麦时,一直返回错误 -2 EOF,询问得知,该错误的解释信息是"Service ...
- [Android 逆向]绕过小米需插卡安装apk限制
1. 确保自己手机是root的了 2. 给手机安装busybox,使可以用vi编辑文件 安装方法: 0. adb shell getprop ro.product.cpu.abi 获得 cpu架构信息 ...
- 以二进制文件安装K8S之部署Master高可用集群
如下以二进制文件方式部署安全的Kubernetes Master高可用集群,具体步骤如下: 1.下载Kubernetes服务的二进制文件 2.部署kube-apiserver服务 3.创建客户端CA证 ...
- 硬件开发笔记(十一):Altium Designer软件介绍、安装过程和打开pcb工程测试
前言 前面做高速电路,选择是阿li狗,外围电路由于读者熟悉AD,使用使用ad比较顺手,非高速电路就使用AD了,其实AD也可以做高速电路,由于笔者从13年开始做硬是从AD9开始的,所以开始切入AD做 ...
- TCP Server and Client Demo
server.go package main import ( "bufio" "fmt" "io" "net" &qu ...
- 【Azure 环境】 介绍两种常规的方法来监视Window系统的CPU高时的进程信息: Performance Monitor 和 Powershell Get-Counter
问题描述 部署在Azure上的VM资源,偶尔CPU飙高,但是发现的时候已经恢复,无法判断当时High CPU原因. 在Windows系统中,有什么方式能记录CPU被进程占用情况,查找出当时是排名前列的 ...
