1.模板编译入口
在初始化时,传入的options参数中有el属性,则进行模板渲染。其中主要的渲染函数为$mount()。//将模板挂载在HTML上
进行render判断,template判断,什么情况下,最终都是将模板转换为render函数进行渲染。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| // 如果有el属性 进行模板渲染 if (vm.$options.el) { vm.$mount(vm.$options.el); } if (!options.render) { // 如果存在template属性 let template = options.template;
if (!template && el) { // 如果不存在render和template 但是存在el属性 直接将模板赋值到el所在的外层html结构(就是el本身 并不是父元素) template = el.outerHTML; }
// 最终需要把tempalte模板转化成render函数 if (template) { const render = compileToFunctions(template); options.render = render; } }
|
2.核心方法compileToFunctions
1 2 3 4 5
| let ast = parse(template); //将html代码转成ast树 let code = generate(ast); //通过ast代码生成render函数 // 使用with语法改变作用域为this 之后调用render函数可以使用call改变this 方便code里面的变量取值 let renderFn = new Function(`with(this){return ${code}}`); return renderFn
|
主要是通过该方法,生成ast树,根据ast树生成render函数返回
3.解析html并生成ast
使用正则表达式匹配开始和结束标签和文本解析并生成ast //通过栈来存放匹配到的标签,然后逐一处理,最后生成
### 4.根据ast重新生成代码
拿到生成好的 ast 之后 需要把 ast 转化成类似_c(‘div’,{id:”app”},_c(‘div’,undefined,_v(“hello”+_s(name)),_c(‘span’,undefined,_v(“world”))))这样的字符串 //其中也会处理指令之类的字符
### 5.code字符串生成render函数
1 2 3 4 5 6
| export function compileToFunctions(template) { let code = generate(ast); // 使用with语法改变作用域为this 之后调用render函数可以使用call改变this 方便code里面的变量取值 比如 name值就变成了this.name let renderFn = new Function(`with(this){return ${code}}`); return renderFn; }
|
6.小结
在Vue构造函数当中定义,初始化时调用挂载在Vue原型上的mount函数,其中核心函数是compileToFunction函数,先将template模板解析成AST树,再将AST树转化成render函数,最后根据render函数递归创建节点。