设为首页 加入收藏

TOP

Vue.js 源码分析(三) 基础篇 模板渲染 el、emplate、render属性详解(二)
2019-09-17 19:00:11 】 浏览:63
Tags:Vue.js 源码 分析 基础 模板 渲染 emplate render 属性 详解
this); } return this } } else if (el) { //如果templtate不存在但是el存在,则获取调用getOuterHTML()函数获取el的outerHTML属性,getOuterHTML()定义在10933行,也就是末尾,用户获取DOM的outerHTML template = getOuterHTML(el); } if (template) { /* istanbul ignore if */ if ("development" !== 'production' && config.performance && mark) { mark('compile'); } var ref = compileToFunctions(template, { shouldDecodeNewlines: shouldDecodeNewlines, shouldDecodeNewlinesForHref: shouldDecodeNewlinesForHref, delimiters: options.delimiters, comments: options.comments }, this); //这里调用compileToFunctions()将template解析成一个render函数,并返回 var render = ref.render; var staticRenderFns = ref.staticRenderFns; options.render = render; options.staticRenderFns = staticRenderFns; /* istanbul ignore if */ if ("development" !== 'production' && config.performance && mark) { mark('compile end'); measure(("vue " + (this._name) + " compile"), 'compile', 'compile end'); } } } return mount.call(this, el, hydrating) };
compileToFunctions函数是由createCompiler()返回的(这里有点绕,研究代码的时候在里面绕了好几天),我把大致主体贴出来,如下:
var baseOptions ={}                                                     //编译的配置项 第9802行
function createCompileToFunctionFn(compile){
  var cache = Object.create(null);  
  return return function compileToFunctions(template, options, vm) {    //编译时先执行这里
    /**/
    compile(template,options)       
    /**/
  }
}
function createCompilerCreator(baseCompile){
  return function(baseOptions){
    function compile(template, options) {/**/}
              return {
                  compile: compile,
                  compileToFunctions: createCompileToFunctionFn(compile)    //难点:匿名函数返回的值中又调用了createCompileToFunctionFn函数
              }
  }
}
var createCompiler = createCompilerCreator(function(){                //传入一个匿名函数
        var ast = parse(template.trim(), options);                          //编译时,第二步:再执行这里
        if (options.optimize !== false) {          
              optimize(ast, options);
        }
        var code = generate(ast, options);         
        return {ast: ast,render: code.render,staticRenderFns: code.staticRenderFns}   //最后返回一个对象
})
var ref$1 = createCompiler(baseOptions);
var compileToFunctions = ref$1.compileToFunctions;                  //编译的入口文件

是不是有点晕呢,我举一个例子就能看明白了,如下:

    function show(show){      //shou函数也直接返回一个匿名函数,带一个参数
      return function(info){
        show(info)              //show通过作用域链就可以访问到参数的show函数了
      }
    }

    var info=show(function(info){
      console.log(info)
    })                          //这里执行show函数,传入一个匿名函数
    info({name:'gsz'})     //控制台输出:{name: "gsz"}

Vue内部看得晦涩是因为传参的时候都注明了一个函数名,其实这个函数名是可以忽略的,这样看起来会更清晰一点    注:这样设计是为了跨平台一些代码的复用和存放吧,代码结构在node下更好理解一点

compileToFunctions函数内部会调用parse()将模板经过一系列的正则解析,用一个AST对象保存,然后调用generate()做静态节点标记,最后调用generate生成一个render函数

以上面的第一个Vue实例来说,parse()解析后的AST对象如下:

、再通过generate()后生成如下一个对象,其中render就是最终要执行的render函数了

compileToFunctions函数返回值是一个对象,以上面的第一个vue实例为例,返回后的信息如下:
{
  render:"(function anonymous() {with(this){return _c('div',{attrs:{"id":"app1"}},[_v(_s(message))])}})",     //最终渲染出来的render函数
  staticRenderFns:Function[]                                                    //如果是静态节点,则保存到这里
}
以后分析到每个API时这里会单独分析的
最后在mountcomponent()函数内会以当前Vue实例为上下文,执行该render函数(在2739行),此时就会完成渲染watch的收集,并生成虚拟VNode,最后调用_update()方法生成真实DOM节点。
首页 上一页 1 2 下一页 尾页 2/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇Javascript 防扒站,防止镜像网站 下一篇Vue.js 源码分析(一) 代码结构

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目