代码 执行 结果

代码

function generate(rootAst) {
  function genStatic(el) {
    el.staticProcessed = true;
    return `_m(${0})`;
  }
  // 处理有if的ast
  function genIf(el) {
    el.ifProcessed = true;
    if (!el.ifConditions.length) {
      return '_e()';
    }
    return `(${el.ifConditions[0].exp})?${genElement(el.ifConditions[0].block)}: _e()`;
  }
  // 处理有for的ast
  function genFor(el) {
    el.forProcessed = true;

    const exp = el.for;
    const alias = el.alias.replace(/\(/gi, '').replace(/\)/gi, '');
    const iterator1 = el.iterator1 ? `,${el.iterator1}` : '';
    const iterator2 = el.iterator2 ? `,${el.iterator2}` : '';
    return `_l((${exp}),` + `function(${alias}${iterator1}${iterator2}){` + `return ${genElement(el)}` + '})';
  }
  // 处理普通文本
  function genText(el) {
    return `_v(${el.expression})`;
  }
  // 根据el的type判断执行生成文本节点代码串方法,还是生成标签节点代码串方法
  function genNode(el) {
    if (el.type === 1) {
      return genElement(el);
    } else {
      return genText(el);
    }
  }
  // 处理子节点,同时得到staticClass、class,用,拼接geneNode执行后的代码字符串
  function genChildren(el) {
    const children = el.children;

    if (children && children.length > 0) {
      return `${children.map(genNode).join(',')}`;
    }
  }
  // 判断当前节点是否有if,for,判断用genIf,还是genFor
  function genElement(el) {
    if (el.static && !el.staticProcessed) {
      return genStatic(el);
      // 如果ast中有if,并且已经把if转成了代码字符串
    } else if (el.if && !el.ifProcessed) {
      return genIf(el);
      // 如果ast中有for,并且已经把for转成了代码字符串
    } else if (el.for && !el.forProcessed) {
      return genFor(el);
    } else {
      // 那么就获取下一级(children)
      const children = genChildren(el);
      let code;
      code = `_c(${el.tag},{
              staticClass: ${el.attrsMap && el.attrsMap[':class']},
              class: ${el.attrsMap && el.attrsMap['class']},
          }${children ? `,${children}` : ''})`;
      // 最终返回一个深度遍历完后的代码字符串
      return code;
    }
  }
  // 执行genElement方法,ast不存在,返回一个空div
  const code = rootAst ? genElement(rootAst) : '_c("div")';
  return {
    render: `with(this){return ${code}}`
  };
}

执行

var html = '<div :class="obj.name" class="test" data-name="div" v-if="index>0" v-for="(item,index) in arr"><!-- hello --><img src="logo.png"/><p>hello world{{name}}</p></div>';
const ast = parse(html);
const opt = optimize(ast);
const gen = generate(opt);
console.log(gen);
console.log(new Function(gen.render));

结果

// gen
{
  render: `with(this){return (index>0)?_l((arr),function(item,index){return _c(div,{staticClass: obj.name,class: test,},_v(undefined),_m(0),_c(p,{staticClass: undefined,class: undefined,},_v("hello world"+_s(name))))}): _e()}`;
}
// Function
function anonymous() {
  with (this) {
    return index > 0
      ? _l(arr, function(item, index) {
          return _c(
            div,
            {
              staticClass: obj.name,
              class: test
            },
            _v(undefined),
            _m(0),
            _c(
              p,
              {
                staticClass: undefined,
                class: undefined
              },
              _v('hello world' + _s(name))
            )
          );
        })
      : _e();
  }
}

暂无评论