介绍
这篇文章将为大家详细讲解有关角怎样由模板生成DOM树,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。
角等现代Web框架极大的提高了开发效率,比如我们经常会在开发过程中写出类似下面的代码:
& lt; div> ,,{{标题}} & lt;/div> export class  AppComponent {=,title & # 39;角# 39;; }
这种模板写法并不是HTML原生支持的,那么角又是如何转换这些代码,并显示成我们期望的界面呢?首先我们来看看角把上述代码编译成什么样子:
,…省略了其他代码 i0。? ? elementStart (0,,“div"); i0。? ?文本(1,,,,hello 角\ n"); i0。? ? elementEnd () ,……省略了其他代码
可以看的到,角把我们写的模板编译成指令的方式,然后通过这些指令生成对应的HTML。这个过程包含两个步骤:
- <李>
把模板编译成上面的产物
李> <李>执行产物代码生成HTML
李>本文主要围绕步骤二进行展开,步骤一的话可能会在后续另写一篇进行阐述。
观察上面的产物代码,我们不难发现有三个主要方法:elementStart,文本,elementEnd。从它们的命名不难推测,这三个方法的作用分别是开始生成标签,内容赋值,闭合标签。下面我们来尝试自己实现这几个方法,最简单的基础版本大概会是这样:
let currentNode:, Node |, null =,空; let currentParent:, Node |, null =,空; function 补丁(主持人:,Node |, DocumentFragment,,呈现:,(),=祝辞,空白):,void { currentNode 才能=,主机; 渲染才能(); } function elementOpen (tagName:字符串):,void { 时间=currentParent 才能;currentNode; const 才能;element =, document.createElement (tagName); currentParent !才能.appendChild(元素); 时间=currentNode 才能;元素; } function 文本(textContent:字符串):,void { currentNode !才能.textContent =, textContent; } function elementEnd (tagName:字符串):,void { 时间=currentNode 才能;currentParent; 时间=currentParent 才能;currentNode ! .parentNode; }
然后在HTML中可以这样使用:
, & lt; div id=癱ontainer"祝辞& lt;/div> ,& lt; script> ,function 使(),{ elementOpen才能(& # 39;div # 39;); 文本才能(& # 39;div 内容# 39;); ,,elementOpen (& # 39; p # 39;); ,,文本(& # 39;p 内容# 39;); ,,elementEnd (& # 39; p # 39;); elementEnd才能(& # 39;div # 39;); ,} ,补丁(. getelementbyid(& # 39;容器# 39;),,渲染); ,& lt;/script>
上述代码中,文本方法参数都被写固定了,实际生成的代码可能类似于文本(Comp.title)这种形式。那么既然是以变量的形式赋值,当用户进行操作的时候,更新这个变量的值,岂不是又要完全重新执行一遍补丁函数么?我们知道DOM操作是耗时的,当我们的项目较大时,如果不采取优化措施,势必会影响框架性能。为此我们很容易想到的一个优化思路,在再次执行补丁函数时,如果DOM节点已经存在我们就重复利用,不再去重新创建并插入DOM树。基于这个思路,我们来更新一下代码:
let currentNode:, Node |, null =,空; let currentParent:, Node |, null =,空; function 补丁(主持人:,Node |, DocumentFragment,,呈现:,(),=祝辞,空白):,void { currentNode 才能=,主机; 渲染才能(); } function elementOpen (tagName:字符串):,void { 时间=currentParent 才能;currentNode; const 才能;firstChild =, (currentParent as 元素).firstElementChild; if 才能;(firstChild ,,, firstChild.tagName.toLowerCase (),===, tagName), { ,,,currentParent =,写上; ,,,返回; ,,} const 才能;element =, document.createElement (tagName); currentParent !才能.appendChild(元素); 时间=currentNode 才能;元素; } function 文本(textContent:字符串):,void { if 才能;(currentNode .textContent !==, textContent), { ,,,currentNode ! .textContent =, textContent; ,,} } function elementEnd (tagName:字符串):,void { 时间=currentNode 才能;currentParent; 时间=currentParent 才能;currentNode ! .parentNode; }角怎样由模板生成DOM树