Open Twlig opened 2 years ago
模板编译分为三部分:
解析器分为HTML解析器、文本解析器以及过滤器解析器,最主要的就是HTML解析器。HTML解析器在解析HTML的过程中会不断触发各种钩子函数,包括开始标签钩子函数、结束标签钩子函数、文本钩子函数和注释钩子函数。
从前向后解析,遇到开始标签触发钩子函数start,把当前构建节点入栈;遇到结束标签触发钩子函数end,从栈中弹出一个节点。
<div> <h1>我是zzy</h1> <p>今年22岁</p> </div>
上述模板被解析成AST过程:触发start钩子函数div入栈,触发start钩子函数h1入栈,触发text钩子函数,触发end钩子函数h1出栈,触发start钩子函数p入栈,触发text钩子函数,触发end钩子函数p出栈,触发end钩子函数div出栈。
构建成一颗AST:三层,div—h1—文本
—p—文本
优化器的作用就是找出静态子树并打上标记。静态子树是指在AST中永远都不会变的节点。例如:一个纯文本节点,而带有变量的文本节点就不是静态子树。
标记静态子树的好处:
主要分为两步:
静态根节点是指,该节点下面所有子节点都是静态节点,并且该节点的父级节点是动态节点。
{ type: 1, tag: 'p', staticRoot: true, static: true, ... }
获取代码字符串
代码生成器将AST转换成渲染函数中的内容,这个内容被称为“代码字符串”。 执行渲染函数后会生成虚拟节点,之所以可以生成虚拟节点,是因为代码字符串中有许多函数调用。
<p title="nihao" @click="c">1</p>
with(this){ return _c( 'p', { attrs:{"title":"nihao"}, on:{"click":c} }, [_v("1")] ); }
其中_c是createElement函数,_v是createTextNode函数,_s是toString函数别名。
_c
_v
_s
使用代码字符串
将代码字符串放到函数里,这个函数就是渲染函数。当渲染函数被导出到外界后,模板编译的任务就完成了。
const code = `with(this){return 'Hello!'}` const hello = new Function(code) hello() //Hello!
Vue的渲染流程
模板编译成渲染函数
模板编译分为三部分:
解析器
解析器分为HTML解析器、文本解析器以及过滤器解析器,最主要的就是HTML解析器。HTML解析器在解析HTML的过程中会不断触发各种钩子函数,包括开始标签钩子函数、结束标签钩子函数、文本钩子函数和注释钩子函数。
从前向后解析,遇到开始标签触发钩子函数start,把当前构建节点入栈;遇到结束标签触发钩子函数end,从栈中弹出一个节点。
上述模板被解析成AST过程:触发start钩子函数div入栈,触发start钩子函数h1入栈,触发text钩子函数,触发end钩子函数h1出栈,触发start钩子函数p入栈,触发text钩子函数,触发end钩子函数p出栈,触发end钩子函数div出栈。
构建成一颗AST:三层,div—h1—文本
—p—文本
优化器
优化器的作用就是找出静态子树并打上标记。静态子树是指在AST中永远都不会变的节点。例如:一个纯文本节点,而带有变量的文本节点就不是静态子树。
标记静态子树的好处:
主要分为两步:
静态根节点是指,该节点下面所有子节点都是静态节点,并且该节点的父级节点是动态节点。
代码生成器
获取代码字符串
代码生成器将AST转换成渲染函数中的内容,这个内容被称为“代码字符串”。 执行渲染函数后会生成虚拟节点,之所以可以生成虚拟节点,是因为代码字符串中有许多函数调用。
模板
代码字符串
其中
_c
是createElement函数,_v
是createTextNode函数,_s
是toString函数别名。使用代码字符串
将代码字符串放到函数里,这个函数就是渲染函数。当渲染函数被导出到外界后,模板编译的任务就完成了。