vue编译原理之vue-template-compiler
vue-template-compiler是编译vue模板的包,传入模板返回AST抽象语法树。const compiler = require('vue-template-compiler')const val = compiler.compile('<span class="active" :total="count">666</span>')输出结果如下:const r
vue-template-compiler是编译vue模板的包,传入模板返回AST抽象语法树。
const compiler = require('vue-template-compiler')
const val = compiler.compile('<span class="active" :total="count">666</span>')
输出结果如下:
const res = {
ast: {
type: 1,
tag: 'span',
attrsList: [ { name: 'total', value: 'count' } ],
attrsMap: { class: 'active', ':total': 'count' },
rawAttrsMap: {},
parent: undefined,
children: [ { type: 3, text: 666, static: true } ],
plain: false,
staticClass: '"active"',
hasBindings: true,
attrs: [ { name: 'total', value: 'count', dynamic: false } ],
static: false,
staticRoot: false
},
render: `with(this){return _c('span',{staticClass:"active",attrs:{"total":count}},[_v("666")])}`,
staticRenderFns: [],
errors: [],
tips: []
}
可以看到对象中有ast属性和render函数,其实ast是为了生成render函数用的。
with (this) {
return _c(
'span',
{ staticClass: "active", attrs: { "total": count } },
[_v("666")]
)
}
render函数回调用很多的函数,如果 _c,_v 那么这些都来自哪里呢?
其实是渲染时候用的的辅助函数,源码路径 https://github.com/vuejs/vue/blob/dev/src/core/instance/render-helpers/index.js
export function installRenderHelpers (target: any) {
target._o = markOnce
target._n = toNumber
target._s = toString
target._l = renderList
target._t = renderSlot
target._q = looseEqual
target._i = looseIndexOf
target._m = renderStatic
target._f = resolveFilter
target._k = checkKeyCodes
target._b = bindObjectProps
target._v = createTextVNode
target._e = createEmptyVNode
target._u = resolveScopedSlots
target._g = bindObjectListeners
target._d = bindDynamicKeys
target._p = prependModifier
}
可是上面没有没有_c,我们继续寻找源码可以发现在 initRender 这里,路径 https://github.com/vuejs/vue/blob/dev/src/core/instance/render.js
vm._c = (a, b, c, d) => createElement(vm, a, b, c, d, false)
createElement 就是创建虚拟节点 VNode。路径 https://github.com/vuejs/vue/blob/dev/src/core/vdom/create-element.js
VNode 可以在Vue实例上查看。
<body>
<span id="app" class="active" :total="count">666</span>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
var app = new Vue({
el: '#app',
data: {
count: 666
}
})
console.log(app)
</script>
</body>
总结:vue在渲染阶段会把模板编译为AST,然后根据AST生成render函数,底层通过调用render函数会生成VNode创建虚拟DOM。
具体VNode的创建原理我之后再写文章单独分析。
更多推荐
所有评论(0)