Vue Compile - ChoDragon9/posts GitHub Wiki
<Comp></Comp>
<div>
<span></span>
</div>
render() {
const Comp = resolveComponent('Comp', this)
return createFragment([
createComponentVNode(Comp, null, null, 0),
createElementVNode('div', null, [
createElementVNode('div', null, null, 0)
], 2),
], 8)
}
<Comp>
<div>{{ hello }}</div>
</Comp>
render() {
return h(Comp, null, {
default: () => [h('div', this.hello)]
}, 16)
}
<div>
<span class="foo">
Static
</span>
<span>
{{ dynamic }}
</span>
</div>
const __static1 = h('span', {
class: 'foo'
}, 'Static')
render() {
return h('div', [
__static1,
h('span', this.dynamic)
])
}
<div id="foo" class="bar">
{{ text }}
</div>
const __props1 = {
id: 'foo',
class: 'bar'
}
render() {
return h('div', __props1, this.text)
}
Vue는 Vue.compile API를 사용해서 <template>
를 Virtual DOM으로 만든다.
각 요소별로 어떻게 변경하는 지 정리해봤다.
<h1>{{blogTitle}}</h1>
render: function (createElement) {
return createElement('h1', this.blogTitle)
}
// @returns {VNode}
createElement(
// {String | Object | Function}
// An HTML tag name, component options, or async
// function resolving to one of these. Required.
'div',
// {Object}
// A data object corresponding to the attributes
// you would use in a template. Optional.
{
// (see details in the next section below)
},
// {String | Array}
// Children VNodes, built using `createElement()`,
// or using strings to get 'text VNodes'. Optional.
[
'Some text comes first.',
createElement('h1', 'A headline'),
createElement(MyComponent, {
props: {
someProp: 'foobar'
}
})
]
)
{
// Same API as `v-bind:class`, accepting either
// a string, object, or array of strings and objects.
class: {
foo: true,
bar: false
},
// Same API as `v-bind:style`, accepting either
// a string, object, or array of objects.
style: {
color: 'red',
fontSize: '14px'
},
// Normal HTML attributes
attrs: {
id: 'foo'
},
// Component props
props: {
myProp: 'bar'
},
// DOM properties
domProps: {
innerHTML: 'baz'
},
// Event handlers are nested under `on`, though
// modifiers such as in `v-on:keyup.enter` are not
// supported. You'll have to manually check the
// keyCode in the handler instead.
on: {
click: this.clickHandler
},
// For components only. Allows you to listen to
// native events, rather than events emitted from
// the component using `vm.$emit`.
nativeOn: {
click: this.nativeClickHandler
},
// Custom directives. Note that the `binding`'s
// `oldValue` cannot be set, as Vue keeps track
// of it for you.
directives: [
{
name: 'my-custom-directive',
value: '2',
expression: '1 + 1',
arg: 'foo',
modifiers: {
bar: true
}
}
],
// Scoped slots in the form of
// { name: props => VNode | Array<VNode> }
scopedSlots: {
default: props => createElement('span', props.text)
},
// The name of the slot, if this component is the
// child of another component
slot: 'name-of-slot',
// Other special top-level properties
key: 'myKey',
ref: 'myRef',
// If you are applying the same ref name to multiple
// elements in the render function. This will make `$refs.myRef` become an
// array
refInFor: true
}
<ul v-if="items.length">
<li v-for="item in items">{{ item.name }}</li>
</ul>
<p v-else>No items found.</p>
props: ['items'],
render: function (createElement) {
if (this.items.length) {
return createElement('ul', this.items.map(function (item) {
return createElement('li', item.name)
}))
} else {
return createElement('p', 'No items found.')
}
}
<input v-model="text">
props: ['value'],
render: function (createElement) {
var self = this
return createElement('input', {
domProps: {
value: self.value
},
on: {
input: function (event) {
self.$emit('input', event.target.value)
}
}
})
}