vue-template-compiler 的原理

什么是 Vue 模板?

Vue 模板是一种用 HTML 语法来描述 Vue 组件的视图的方式,

例如:

<template><div class="example">{{ msg }}</div>
</template>
<script>export default {data() {return {msg: "Hello world!",};},};
</script>
<style>.example {color: red;}
</style>

这里的 template 标签内的内容就是 Vue 模板,它可以使用一些 Vue 特有的指令和表达式,例如 v-if、v-for、{{ }} 等,来实现动态的视图渲染。

为什么要预编译 Vue 模板?

Vue 模板本身是一种字符串,要想让它在浏览器中显示出来,就需要将它转换为一个可以创建和更新 DOM 的函数,这个函数就叫做渲染函数。

Vue 提供了两种方式来生成渲染函数:

  • 运行时编译:这种方式是在浏览器中,使用 vue-template-compiler 的浏览器版本,将模板字符串动态地编译为渲染函数,然后执行渲染函数,创建和更新 DOM。这种方式的优点是可以使用任意的模板字符串,甚至可以从服务器端获取模板字符串,实现动态的视图渲染。缺点是需要额外的编译时间和编译器的代码体积,以及可能的 CSP 限制,因为编译器会使用 new Function 来创建渲染函数,这在一些严格的安全策略下是不允许的。
  • 预编译:这种方式是在构建时,使用 vue-template-compiler 的 Node.js 版本,将模板字符串静态地编译为渲染函数,并将渲染函数打包到最终的 js 文件中,然后在浏览器中直接执行渲染函数,创建和更新 DOM。这种方式的优点是可以避免运行时编译的开销和限制,提高性能和安全性。缺点是不能使用动态的模板字符串,只能使用固定的模板字符串,或者使用 render 函数来手动编写渲染函数。

预编译 Vue 模板的好处是显而易见的,它可以让我们的 Vue 应用更快更安全地运行,而不需要牺牲太多的灵活性。因此,预编译 Vue 模板是一种推荐的做法,尤其是在使用 webpack 或其他构建工具的情况下,我们可以很方便地使用 vue-loader 或其他方式来实现预编译。

vue-template-compiler 是如何工作的?

vue-template-compiler 的工作原理是,它会将 Vue 模板字符串转换为一个包含渲染函数和静态渲染函数的对象,这个对象可以被 vue-loader 或其他方式引用,从而创建一个 Vue 组件。

分为以下几个步骤:

  • 首先,它会使用 html-parser 来解析模板字符串,将其转换为一个抽象语法树 (AST)。AST 是一种用 JavaScript 对象来表示 HTML 结构的方式,它包含了元素、属性、文本、表达式等节点,以及它们之间的关系。例如,上面的模板字符串的 AST 大致如下:

    {type: 1, // 元素节点tag: "div", // 标签名attrsList: [{ name: "class", value: "example" }], // 属性列表attrsMap: { class: "example" }, // 属性映射children: [{type: 2, // 表达式节点expression: "_s(msg)", // 表达式内容text: "{{ msg }}", // 文本内容},], // 子节点列表
    }
    
  • 然后,它会使用 optimize 来优化 AST,标记出静态节点和静态根节点,这样可以在渲染时跳过它们,提高性能。静态节点是指不依赖于数据的节点,例如纯文本节点或固定属性的元素节点。静态根节点是指只有一个子节点,并且这个子节点是静态节点的元素节点。例如,上面的模板字符串的 AST 中,div 节点就是一个静态根节点,它的子节点 {{ msg }} 就是一个静态节点。optimize 会在 AST 的每个节点上添加一个 static 属性,表示是否是静态节点,以及一个 staticRoot 属性,表示是否是静态根节点。例如,上面的模板字符串的 AST 的 optimize 后的结果大致如下:

    {type: 1,tag: "div",attrsList: [{ name: "class", value: "example" }],attrsMap: { class: "example" },children: [{type: 2,expression: "_s(msg)",text: "{{ msg }}",static: true, // 静态节点},],static: false, // 非静态节点staticRoot: true, // 静态根节点
    }
    
  • 接着,它会使用 codegen 来生成渲染函数的代码,包括创建元素、绑定属性、插入文本、添加事件等。codegen 会遍历 AST,将其中的节点转换为相应的渲染函数的代码片段,然后将这些代码片段拼接成一个完整的渲染函数,并添加一些必要的辅助函数和变量。例如,上面的模板字符串的 AST 的 codegen 后的结果大致如下:

    with (this) {return _c("div",{ staticClass: "example" },[_v(_s(msg))],1 /* STATIC */);
    }
    

    这里的 _c、_v、_s 等都是 Vue 提供的辅助函数,用于创建元素、创建文本、转义字符串等。最后的 1 是一个标志位,表示这个节点是静态的,可以跳过更新。

  • 最后,它会导出一个包含渲染函数和静态渲染函数的对象,可以被 vue-loader 或其他方式引用,从而创建一个 Vue 组件。渲染函数是用于创建和更新动态节点的函数,静态渲染函数是用于创建和缓存静态节点的函数。例如,上面的模板字符串的导出结果大致如下:

    export default {render: function () {with (this) {return _c("div",{ staticClass: "example" },[_v(_s(msg))],1 /* STATIC */);}},staticRenderFns: [],
    };
    

    这里的 staticRenderFns 是一个空数组,表示没有静态节点需要缓存。如果有静态节点需要缓存,它会包含一些静态渲染函数,用于创建和返回静态节点。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/200972.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

软件测试面试题解析--什么题是必问的?

设计测试用例的主要方法有哪些&#xff1f;简述一下缺陷的生命周期&#xff1f;测试流程&#xff1f;项目流程&#xff1f;验收测试中和β测试区别&#xff1f;如何维护测试用例&#xff1f;每天测多少用例怎么分配的测试的一天能找多少bug你在上一家公司&#xff0c;写没写过测…

Selenium+Unittest+HTMLTestRunner框架更改为Selenium+Pytest+Allure(二)

1 代码框架 整体项目结构如图&#xff1a; Common&#xff1a;公共库 Logs&#xff1a; 日志目录 Page&#xff1a; 页面元素 Report&#xff1a;测试报告 TestCase&#xff1a;测试用例 TestData&#xff1a; 测试数据 2 单模块运行 直接上代码&#xff1a; # -*- coding…

详细介绍如何使用 SSD 进行实时物体检测:单次 MultiBox 探测器-含源码

介绍 在实时对象检测中,主流范例传统上采用多步骤方法,包括边界框、像素或特征重采样以及高质量分类器应用的提议。虽然这种方法已经实现了高精度,但其计算需求往往阻碍了其对实时应用的适用性。然而,单次多框检测器 (SSD) 代表了基于深度学习的对象检测的突破性飞跃。SSD…

SpringCloud | Dubbo 微服务实战——注册中心详解

前言 「作者主页」&#xff1a;雪碧有白泡泡 「个人网站」&#xff1a;雪碧的个人网站 |Eureka,Nacos,Consul,Zookeeper在Spring Cloud和Dubbo中实战 引言 在项目开发过程中&#xff0c;随着项目不断扩大&#xff0c;也就是业务的不断增多&#xff0c;我们将采用集群&#xf…

day7 四数之和为x

vector<vector<int>> fourSum(vector<int>& nums, int target) { vector<vector<int>> result; sort(nums.begin(), nums.end()); for (int k 0; k < nums.size(); k) { // 剪枝处理 if (nums[k] > target && nums[k] > …

647. Palindromic Substrings 516. Longest Palindromic Subsequence

647. Palindromic Substrings Given a string s, return the number of palindromic substrings 回文子串 in it. A string is a palindrome when it reads the same backward as forward. A substring is a contiguous sequence of characters within the string. nomal: …

LeetCode //C - 221. Maximal Square

221. Maximal Square Given an m x n binary matrix filled with 0’s and 1’s, find the largest square containing only 1’s and return its area. Example 1: Input: matrix [[“1”,“0”,“1”,“0”,“0”],[“1”,“0”,“1”,“1”,“1”],[“1”,“1”,“1”,…

图解Spark Graphx实现顶点关联邻接顶点的collectNeighbors函数原理

一、场景案例 在一张社区网络里&#xff0c;可能需要查询出各个顶点邻接关联的顶点集合&#xff0c;类似查询某个人关系比较近的都有哪些人的场景。 在用Spark graphx中&#xff0c;通过函数collectNeighbors便可以获取到源顶点邻接顶点的数据。 下面以一个例子来说明&#…

C语言--每日选择题--Day37

第一题 1. 有以下说明语句&#xff1a;则下面引用形式错误的是&#xff08;&#xff09; struct Student {int num;double score; };struct Student stu[3] {{1001,80}, {1002,75}, {1003,91}} struct Student *p stu; A&#xff1a;p->num B&#xff1a;(p).num C&#…

[论文精读]序列建模使大视觉模型的规模化学习成为可能

本博客是一篇最新论文的精读&#xff0c;论文为UC伯克利大学及约翰霍普金斯大学相关研究者新近(2023.12.1)在arxiv上上传的《Sequential Modeling Enables Scalable Learning for Large Vision Models》 。知名科技新媒体“新智元”给与本文极高评价&#xff0c;并以《计算机视…

STM32(PWM、ADC)

1、PWM 定义 PWM&#xff0c;全称为脉冲宽度调制&#xff08;Pulse Width Modulation&#xff09;&#xff0c;它通过改变信号的高电平和低电平的持续时间比例来控制输出信号的平均功率或电压。 PWM&#xff0c;全称为脉冲宽度调制&#xff08;Pulse Width Modulation&#xff…

FPGA实现电机位置环、速度环双闭环PID控制

一、设计思路 主要设计思路就是根据之前写的一篇FPGA实现电机转速PID控制&#xff0c;前面已经实现了位置环的控制&#xff0c;思想就是通过电机编码器的当前位置值不断地修正PID去控制速度。 那为了更好的实现控制&#xff0c;可以在位置环后加上速度环&#xff0c;实现电机位…

目标检测YOLO系列从入门到精通技术详解100篇-【目标检测】3D目标检测

目录 前言 几个高频面试题目 怎样制作目标检测的训练样本图像? 像元值应该如何进行归一化?

scipy

scipy 是什么常用方法 是什么 scipy是Python语言的一个开源数值计算库&#xff0c;主要目的是为科学、工程、计算等领域提供有用的数学算法和函数&#xff0c;包括线性代数、优化、信号处理、傅里叶变换、统计函数等。它是Python科学计算环境的重要组成部分&#xff0c;通常与N…

2021年GopherChina大会-核心PPT资料下载

一、峰会简介 自 Go 语言诞生以来&#xff0c;中国便是其应用最早和最广的国家之一&#xff0c;根据 Jetbrains 在 2021 年初做的调查报告&#xff0c;总体来说目前大概有 110 万专业的开发者 选择 Go 作为其主要开发语言。就其全球分布而言, 居住在亚洲的开发者最多&#xff…

go学习之goroutine和channel

文章目录 一、goroutine(协程)1.goroutine入门2.goroutine基本介绍-1.进程和线程说明-2.程序、进程和线程的关系示意图-3.Go协程和Go主线程 3.案例说明4.小结5.MPG模式基本介绍6.设置Golang运行的CPU数7.协程并发&#xff08;并行&#xff09;资源竞争的问题8.全局互斥锁解决资…

MySQL 8 update语句更新数据表里边的数据

数据重新补充 这里使用alter table Bookbought.bookuser add userage INT after userphone;为用户表bookuser在userphone列后边添加一个类型为INT的新列userage。 使用alter table Bookbought.bookuser add sex varchar(6) after userage ;为用户表bookuser在userage 列后边添…

Oracle-数据库连接数异常上涨问题分析

问题&#xff1a; 用户的数据库在某个时间段出现连接数异常上涨问题&#xff0c;时间持续5分钟左右&#xff0c;并且问题期间应用无法正常连接请求数据库 从连接数的监控上可以看到数据库平常峰值不到100个连接&#xff0c;在问题时间段突然上涨到400以上 问题分析&#xff1a;…

unity | 动画模块之循环滚动选项框

一、作者的话 评论区有人问&#xff0c;有没有竖排循环轮播选项框&#xff0c;我就写了一个 二、效果动画 如果不是你们想要的&#xff0c;就省的你们继续往下看了 三、制作思路 把移动分成里面的方块&#xff0c;还有背景&#xff08;父物体&#xff09;&#xff0c;方块自…

网络模拟与网络仿真

目录 一、概念界定 二、模拟&#xff08;simulation&#xff09;与仿真&#xff08;emulation&#xff09; 2.1 模拟&#xff08;simulation&#xff09; 2.2 仿真&#xff08;emulation&#xff09; 2.3 区分 三、网络模拟与网络仿真 3.1 网络模拟 3.2 网络仿真 3.…