Browse Source

thunkify children

dev
Evan You 9 years ago
parent
commit
1df748d57d
  1. 13
      src/compiler/codegen/index.js
  2. 15
      src/runtime/instance/render.js
  3. 7
      src/runtime/vdom/create-element.js

13
src/compiler/codegen/index.js

@ -1,5 +1,6 @@
import { genHandlers } from './events'
import { genDirectives } from './directives/index'
import { isReservedTag } from '../../runtime/util/dom'
export function generate (ast) {
const code = ast ? genElement(ast) : '__h__("div")'
@ -18,7 +19,10 @@ function genElement (el) {
} else if (el.tag === 'slot') {
return genSlot(el)
} else {
return `__h__('${el.tag}', ${genData(el)}, ${genChildren(el)})`
// if the element is potentially a component,
// wrap its children as a thunk.
const children = genChildren(el, !isReservedTag(el.tag))
return `__h__('${el.tag}', ${genData(el)}, ${children})`
}
}
@ -92,11 +96,14 @@ function genData (el) {
return data.replace(/,$/, '') + '}'
}
function genChildren (el) {
function genChildren (el, asThunk) {
if (!el.children.length) {
return 'undefined'
}
return '[' + el.children.map(genNode).join(',') + ']'
const code = '[' + el.children.map(genNode).join(',') + ']'
return asThunk
? `function(){return ${code}}`
: code
}
function genNode (node) {

15
src/runtime/instance/render.js

@ -85,9 +85,16 @@ export function renderMixin (Vue) {
Vue.prototype.$mount = function (el) {
callHook(this, 'beforeMount')
this.$el = el && query(el)
if (this.$el) {
this.$el.innerHTML = ''
el = this.$el = el && query(el)
if (el) {
// clean element
el.innerHTML = ''
if (el.hasAttributes()) {
const attrs = el.attributes
for (let i = 0, l = attrs.length; i < l; i++) {
el.removeAttribute(attrs[i].name)
}
}
}
this._watcher = new Watcher(this, this._render, this._update)
this._update(this._watcher.value)
@ -103,7 +110,7 @@ export function renderMixin (Vue) {
function resolveSlots (vm, children) {
if (children) {
children = children.slice()
children = children().slice()
const slots = { default: children }
let i = children.length
let name, child

7
src/runtime/vdom/create-element.js

@ -10,12 +10,11 @@ import {
} from '../util/index'
export default function createElement (tag, data, children) {
children = flatten(children)
const parent = renderState.activeInstance
if (typeof tag === 'string') {
let Ctor
if (isReservedTag(tag)) {
return VNode(tag, data, children)
return VNode(tag, data, flatten(children))
} else if ((Ctor = resolveAsset(parent.$options, 'components', tag))) {
return Component(Ctor, data, parent, children)
} else {
@ -26,14 +25,14 @@ export default function createElement (tag, data, children) {
'make sure to provide the "name" option.'
)
}
return VNode(tag, data, children)
return VNode(tag, data, flatten(children()))
}
} else {
return Component(tag, data, parent, children)
}
}
function flatten (children) {
export function flatten (children) {
if (isArray(children)) {
let res = []
for (let i = 0, l = children.length; i < l; i++) {

Loading…
Cancel
Save