角怎样由模板生成DOM树

  介绍

这篇文章将为大家详细讲解有关角怎样由模板生成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树