这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助

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]])))
])
])
}
在渲染函数中,我们可以看到Vue将HTML标记转换为_createVNode_createBlock函数的调用,将指令和表达式转换为相应的JavaScript代码,并使用_toDisplayString函数将表达式的值转换为字符串。最终生成的渲染函数会被Vue用来渲染组件的实例。

本文转载于:

https://juejin.cn/post/7221354195914326073

如果对您有所帮助,欢迎您点个关注,我会定时更新技术文档,大家一起讨论学习,一起进步。

记录-Vue.js模板编译过程揭秘:从模板字符串到渲染函数的更多相关文章

  1. JS预编译过程

    GO和AO 变量的预编译 实例1 console.log(a); var a=1; console.log(a); 实际编译过程: 将a存入预编译对象中,赋值为undefined: 真正的赋值语句当程 ...

  2. smarty 模板编译和变量调节器 模板引入

    <?php require './smarty/Smarty.class.php'; $sm = new Smarty; //$sm->force_compile = true; $sm- ...

  3. Vue 源码解读(10)—— 编译器 之 生成渲染函数

    前言 这篇文章是 Vue 编译器的最后一部分,前两部分分别是:Vue 源码解读(8)-- 编译器 之 解析.Vue 源码解读(9)-- 编译器 之 优化. 从 HTML 模版字符串开始,解析所有标签以 ...

  4. 解决vue.js在编写过程中出现空格不规范报错的情况

    找到build文件夹下面的webpack.base.conf.js文件. 然后打开该文件,找到图下这段代码,把他注释掉. 注释掉之后,再进行子页面等编写的时候,空格不规范的情况下也不会再报错啦.因为这 ...

  5. vscode实现vue.js项目的过程

    https://blog.csdn.net/weixin_37567150/article/details/81291433 https://blog.csdn.net/ywl570717586/ar ...

  6. vue原理:diff、模板编译、渲染过程等

    一.虚拟DOM: 因为DOM操作非常消耗性能,在操作DOM时,会出现DOM的回流(Reflow:元素大小或者位置发生改变)与重绘(元素样式的改变)使DOM重新渲染. 现在的框架Vue和React很少直 ...

  7. vue.js+webpack在一个简单实例中的使用过程demo

    这里主要记录vue.js+webpack在一个简单实例中的使用过程 说明:本次搭建基于Win 7平台 Node.js 安装官网提供了支持多种平台的的LTS版本下载,我们根据需要来进行下载安装.对于Wi ...

  8. Vue.js——60分钟browserify项目模板快速入门

    概述 在之前的一系列vue.js文章,我们都是用传统模式引用vue.js以及其他的js文件的,这在开发时会产生一些问题. 首先,这限定了我们的开发模式是基于页面的,而不是基于组件的,组件的所有代码都直 ...

  9. Vue.js——60分钟browserify项目模板快速入门

    概述 在之前的一系列vue.js文章,我们都是用传统模式引用vue.js以及其他的js文件的,这在开发时会产生一些问题. 首先,这限定了我们的开发模式是基于页面的,而不是基于组件的,组件的所有代码都直 ...

  10. Vue.js系列之三模板语法

    Vue.js 使用了基于 HTML 的模板语法,允许开发者声明式地将 DOM 绑定至底层 Vue 实例的数据.所有 Vue.js 的模板都是合法的 HTML ,所以能被遵循规范的浏览器和 HTML 解 ...

随机推荐

  1. 开源.NetCore通用工具库Xmtool使用连载 - 发送短信篇

    [Github源码] <上一篇> 介绍了Xmtool工具库中的发送邮件类库,今天我们继续为大家介绍其中的发送短信类库. 发送短信就像发送邮件一样,在软件系统中使用非常普遍,甚至比发送邮件还 ...

  2. NodeJs web项目框架Express笔记

    安装 以下都使用Yarn进行. 环境前提: 已经安装NodeJS(及自带的npm), 已经安装Yarn # 全局安装 yarn global add express-generator@4 #查看版本 ...

  3. Failed to bind properties under ” to com.zaxxer.hikari.HikariDataSource

    1.问题说明 今天配置spring boot多数据源,同时用到了oracle和postgresql,结果配置完毕后启动报这个错. 2.原因分析 忘记添加postgresql驱动了!!! 3.解决方案 ...

  4. eclipse解决maven不自动下载jar包问题

    今天在eclipse中import一个maven项目,由于我手工中断了相关pom.xml中配置的jar包下载. 导致项目找不到一些jar包.具体错误见下图: 原因就是有些jar包下载没有完成导致的. ...

  5. Linux上安装和部署git

    本机环境: [git@rhel-server .ssh]$ cat /proc/version Linux version 2.6.32-358.el6.x86_64 1.安装 yum install ...

  6. 4.1k Star!全面的C#/.NET/.NET Core学习、工作、面试指南

    C#/.NET/.NET Core 学习.工作.面试指南 让现在的自己不再迷茫 . GitHub 开源地址:https://github.com/YSGStudyHards/DotNetGuide D ...

  7. pikachu php反序列化漏洞

    原理 php中serialize(),unserialize()这两个函数. 序列化serialize() 序列化说通俗点就是把一个对象变成可以传输的字符串,比如下面是一个对象: class S{ p ...

  8. 案例分享:Qt国产麒麟系统某防“某显示控制项目”(多类设备自动化流程控制,数据分析整合与展示,定位图,深度图,热力图等,多应用协调管控,健壮容错)

    喜报   我司承担的某防"某显示控制项目",已于近日顺利通过湖底验收.   需求   功能简介:  1.多类设备的显示.控制与管理  2.数据的分析与展示,定位图.深度图.热力图等 ...

  9. docker清理已停止的容器

    docker rm -v $(docker ps -aq -f status=exited) 可以将该命令写成shell脚本或者alias.-v参数表示同时清理数据卷

  10. 解决celery与django结合后,分别启动celery和django的进程同时调用定时任务的问题

    django中引入celery后发现在代码中写如下这样的定时任务,启动celery和django的工程后,他们都会调用这个定时任务导致,任务有的时候会冲突出现奇怪的问题.如何解决请继续看. sched ...