children render context

This commit is contained in:
Evan You 2016-04-16 00:05:46 -04:00
parent 1df748d57d
commit c16fc2c427
3 changed files with 27 additions and 14 deletions

View File

@ -102,7 +102,7 @@ function genChildren (el, asThunk) {
}
const code = '[' + el.children.map(genNode).join(',') + ']'
return asThunk
? `function(){return ${code}}`
? `_withContext(function(){return ${code}})`
: code
}

View File

@ -5,7 +5,8 @@ import { callHook } from './lifecycle'
import { getPropValue } from './state'
export const renderState = {
activeInstance: null
activeInstance: null,
context: null
}
export function initRender (vm) {
@ -58,28 +59,39 @@ export function renderMixin (Vue) {
}
}
/**
* Call a render function with this instance as the context.
* This is used to wrap all children thunks in codegen.
*/
Vue.prototype._withContext = function (fn) {
return () => {
const prev = renderState.context
renderState.context = this
return fn()
renderState.context = prev
}
}
Vue.prototype._render = function () {
const {
render,
_renderKey,
_renderData,
_renderChildren
} = this.$options
// resolve slots
const prev = renderState.activeInstance
renderState.activeInstance = this
const { render, _renderKey, _renderData, _renderChildren } = this.$options
// resolve slots. becaues slots are rendered in parent scope,
// we set the activeInstance to parent.
if (_renderChildren) {
resolveSlots(this, _renderChildren)
}
// render
const prev = renderState.activeInstance
renderState.activeInstance = this
// render self
const vnode = render.call(this)
renderState.activeInstance = prev
// set key
vnode.key = _renderKey
// update parent data
if (_renderData) {
mergeParentData(this, vnode.data, _renderData)
}
// restore render state
renderState.activeInstance = prev
return vnode
}

View File

@ -11,11 +11,12 @@ import {
export default function createElement (tag, data, children) {
const parent = renderState.activeInstance
const context = renderState.context || parent
if (typeof tag === 'string') {
let Ctor
if (isReservedTag(tag)) {
return VNode(tag, data, flatten(children))
} else if ((Ctor = resolveAsset(parent.$options, 'components', tag))) {
} else if ((Ctor = resolveAsset(context.$options, 'components', tag))) {
return Component(Ctor, data, parent, children)
} else {
if (process.env.NODE_ENV !== 'production' && !data.svg) {