你想要的 vue 源码分析 · 29
代码 执行 结果
代码
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();
}
}
即可发布评论!
暂无评论
确认评论邮箱
邀请制评论