vue2 中 template 转换成 ast 过程简介

本文简要探讨Vue2中template转化为抽象语法树(AST)的过程,涉及vue的parse阶段。通过了解html parser,如simplehtmlparser,解析HTML模板,从前向后匹配标签、属性等,并触发回调。AST的生成涉及栈操作,提供了一道算法实践题目。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这篇文章主要简单介绍 template 转换成 ast 的过程,也就是 vue 中 parse 的过程。

假设 template 模版为

const template = `<div>
    <div style='color: red'>{{count}}</div>
    <button @click="addCount">addCount</button>
</div>`

首先要了解一下 html parser,vue 中的 parseHTML 是从 simplehtmlparser 修改来的,simplehtmlparser 代码链接:http://erik.eae.net/simplehtmlparser/simplehtmlparser.js

parseHTML 过程其实就是从前向后的字符串匹配过程。html parser 的主要思想如下,从前向后匹配出 html 标签名称、属性、文本节点内容、注释等等,触发对应的回调函数,其中 s 是输入的字符串模版,contentHandler 是匹配到内容后执行的回调函数。

function parseHTML(s, contentHandler) {
    while (s.length > 0) {
        // Comment
        if (s.substring(0, 4) == "<!--") {
            index = s.indexOf("-->");
            if (index != -1) {
                contentHandler.comment(s.substring(4, index));
                s = s.substring(index + 3);
                treatAsChars = false;
            } else {
                treatAsChars = true;
            }
        }
        // end tag
        else if (s.substring(0, 2) == "</") {
            contentHandler.end(sTagName);
        }
        // start tag
        else if (s.charAt(0) == "<") {
            var attrs = parseAttributes(sTagName, sRest);
            contentHandler.start(sTagName, attrs);
        }
        if (treatAsChars) {
            index = s.indexOf("<");
            if (index == -1) {
                contentHandler.chars(s);
                s = "";
            } else {
                contentHandler.chars(s.substring(0, index));
                s = s.substring(index);
            }
        }
    }
}

我们将刚才的模版输入到这个函数中

const handler = {
    start: function (sTagName, oAttrs) {
        console.log('start', sTagName, oAttrs)
    },
    end: function (sTagName) {
        console.log('end', sTagName)
    },
    chars: function (s) {
        console.log('chars', s)
    },
    comment: function (s) {
        console.log('comment', s)
    }
};
parseHTML(template, handler);

这样就可以按顺序匹配到开始标签、标签属性、元素中文本节点、结束标签。

start div []
chars


start div [ { name: 'style', value: 'color: red' } ]
chars {{count}}
end div
chars


start button [ { name: '@click', value: 'addCount' } ]
chars addCount
end button
chars


end div

最后如何生成 AST,就是一道栈相关的算法题啦,大家可以自己尝试一下。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值