前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >「.vue文件的编译」5. 模板编译之基于AST的代码生成

「.vue文件的编译」5. 模板编译之基于AST的代码生成

作者头像
tinyant
发布2023-02-24 10:31:13
4440
发布2023-02-24 10:31:13
举报

本节偷个懒,可以参考这里

经过前面几个步骤,AST上的维护节点的父子关系,并且每个节点上都有足够的信息。

这里根据这些信息来构造render函数,render函数的形式以demo为例

代码语言:javascript
复制
(function anonymous() {
        with (this) {
            return _c('div', {
                staticClass: "container",
                attrs: {
                    "id": "app"
                }
            }, [_c('slot-test', {
                scopedSlots: _u([{
                    key: "header",
                    fn: function (slotProps) {
                        return [_c('div', [_v("name: " + _s(slotProps.user.name))]), _v(" "), _c('div', [_v("sex: " + _s(slotProps.user.sex))])]
                    }
                }])
            }), _v(" "), _c('div', [_v("static node")]), _v(" "), (showSpan) ? _c('span', {
                class: {
                    active: showSpan
                },
                on: {
                    "click": clickHandler
                }
            }, [_v(" show Span")]) : _c('span', {
                on: {
                    "click": clickHandler
                }
            }, [_v("hide Span")]), _v(" "), _l((items), function (item, index) {
                return _c('div', [_c('span', [_v(" " + _s(item))])])
            }), _v(" "), _c('input', {
                directives: [{
                    name: "model",
                    rawName: "v-model",
                    value: (searchText),
                    expression: "searchText"
                }],
                domProps: {
                    "value": (searchText)
                },
                on: {
                    "input": function ($event) {
                        if ($event.target.composing)
                            return;
                        searchText = $event.target.value
                    }
                }
            })], 2)
        }
    }
)

with中的this是vue实例,_u等等都是挂载在该Vue原型上的,_c是直接挂载vm实例上的。

代码语言:javascript
复制
// renderMixin -> installRenderHelpers(Vue.prototype)
// initRender -> vm._c = (a, b, c, d) => createElement(vm, a, b, c, d, false)

总结


整个模板解析分为四个步骤

  1. simple-html-parser 来遍历html字符串,找出元素标签(包括收集属性)、文本
  2. 基于simple-html-parser提供的钩子start/end来解析收集来属性,并创建AST节点,将解析后的信息保存到每个AST节点上。并建立AST节点父子关系,root代表整个AST
  3. optimize:不影响主流程,完全是从创建虚拟DOM和虚拟DOM的diff层面来优化这两个步骤(减少虚拟DOM的创建和diff)
  4. 基于砂上面的AST的代码生成,并非还原为html,而是vue需要的render函数,看到关键的方法_c对应运行时的creatElement用来创建虚拟DOM的。

整体看逻辑还是很清晰的。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-02-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档