持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第26天,点击查看活动详情
vue2模版编译 render 方法 属性格式化介绍 这边文章把属性格式化介绍完了,我们继续下面的逻辑,下面我们就要处理el的子元素了,咱们可以看下AST的结构如图
我们来看下代码
function generate(el) {
// 拿到children的方法
let children = getChildren(el) // 可以把子元素直接拼在后面
let code = `
_c(${el.tag},
${el.attrs.length>0?`${formProps(el.attrs)}`:'undefined'}
${children?`,${children}`:','}
)
`
}
getChildren方法
// 使用的正则表达式
// 获取
function getChildren(el) {
// 循环子元素并且对返回字符串进行拼接
const children = el.children;
if (children) {
// 这里我们需要拼接字符串
return children.map(c=>{
return generateChild(c).jion(',')
})
}
}
generateChild方法又是一个非常复杂的一个方法,我们又要拼接字符串了
// 拼接children的的方法
function generateChild(node) {
// 优先判断是不是AST的type值
if (node.type==1) { // 直接走generate的逻辑
return generate(node)
} else if (node.type==3) { // 如果是文本类型
let text = node.text
// 这里也需要判断是纯文本还是有双大括号纯文本好做
if (!defaultTagRE.test(text)) {
return `_v('${node.text}')`
}
// 处理有双大括号的文本最麻烦
let match,index;
let lastIndex = defaultTagRE.lastIndex = 0;
let textArr = []; // 每一次截取出来的都放在这个数组里
// lastIndex是正则表达是捕获的一个属性,他是会累计的,每捕获成功一次会相加等于10,第两次捕获就会从10开始,就不会从零开始
while (match=defaultTagRE.exec(text)) { // 正则捕获
console.log(match)
// 我们会把match打印出来看一下更加明确
index = match.index; // index是捕获到开始位置
if (index>lastIndex) { // 说明有大括号
// 这是截取大括号之前的文本
textArr.push(JSON.stringify(text.slice(lastIndex,index)))
}
textArr.push(`_s(${match[1].trim()})`)
lastIndex = index+ match[0].length
}
if (lastIndex<text.length) { // 判断lastIndex是是否小于文本长度
// 小于说明还有文本
textArr.push(`${JSON.stringify(text.slice(lastIndex))}`)
}
console.log(textArr)
console.log(`_v(${textArr.join('+')})`)
return `_v(${textArr.join('+')})`
}
}
大家可以看下打印出的match和textArr
上面是match 下面是textArr
可以看下已经拼接好的字符串