合规国际互联网加速 OSASE为企业客户提供高速稳定SD-WAN国际加速解决方案。 广告
## 模版编译 ![](https://img.kancloud.cn/3c/63/3c637d34db3c4ea02574ab79fa79f2f1_1643x487.png) ### 模版编译步骤 1. 将模版编译成 AST ----- 解析器 2. 遍历 AST,标记静态节点,当数据发生变化时,跳过静态节点的更新。不需要生成新的虚拟节点,而是直接克隆已存在的虚拟节点----- 优化器 3. 根据 AST 生成渲染函数 ----- 代码生成器 ![](https://img.kancloud.cn/ac/7e/ac7ea79c12642cf0d9da475a08d6e144_2301x853.png) #### 解析器 解析器有很多小的解析器组成,通过主线将小解析器串在一起。 * 过滤器 -- 解析过滤器 * 文本解析器 -- 解析带变量的文本,生成文本类型的 AST * HTML 解析器 -- 解析模版 ![](https://img.kancloud.cn/20/19/20197ae1d72ee1c639593575ba7c9644_1030x758.png) AST 和 Vnode 的区别 共同点:都是用js中的对象来表示节点 不同点:职责不同 #### 优化器 - 提升性能 #### 代码生成器 将 AST转换成渲染函数中的**内容**,也就是代码字符串 with语法:扩展一个语句的作用域链 缺点:导致数据泄漏 ``` function foo(obj) { with (obj) { a = 2; } } var o1 = { a: 3 }; var o2 = { b: 3 } foo(o1); console.log(o1.a); //2 foo(o2); console.log(o2.a); //underfined console.log(a); //2,a被泄漏到全局作用域上 ``` ``` let obj = { a:"aa", b:"bb", c:"cc" } // 取值 with(obj){ var a = a; var b = b; var c = c; } ``` ``` <p title="123" @click="c"> 1 </p> ``` 生成后的代码字符串 ``` const code = `with(this){return _c('p', {attrs: {"title": "123"}, on: {"click": c}, [_v("1")] )}` ``` 将代码字符串放入函数中 ``` const hello = new Function(`with(this){return 'hello world'}`) ``` 生成渲染函数 hello ,创建 vnode 渲染函数之所以可以生成 vnode,是因为代码字符串中调用了生成vnode的方法,如_c 创建元素节点,_v生成文本节点