Browse Source

adjust named slot resolve check (fix #3819)

dev
Evan You 8 years ago
parent
commit
99ea0f8229
  1. 2
      flow/component.js
  2. 2
      src/core/instance/lifecycle.js
  3. 12
      src/core/instance/render.js
  4. 7
      src/core/vdom/create-component.js
  5. 1
      test/unit/features/component/component-slot.spec.js

2
flow/component.js

@ -52,7 +52,7 @@ declare interface Component {
_isVue: true;
_self: Component;
_renderProxy: Component;
_renderParent: ?Component;
_renderContext: ?Component;
_watcher: Watcher;
_watchers: Array<Watcher>;
_data: Object;

2
src/core/instance/lifecycle.js

@ -141,7 +141,7 @@ export function lifecycleMixin (Vue: Class<Component>) {
}
// resolve slots + force update if has children
if (hasChildren) {
vm.$slots = resolveSlots(renderChildren)
vm.$slots = resolveSlots(renderChildren, vm._renderContext)
vm.$forceUpdate()
}
}

12
src/core/instance/render.js

@ -14,7 +14,8 @@ export function initRender (vm: Component) {
vm.$vnode = null // the placeholder node in parent tree
vm._vnode = null // the root of the child tree
vm._staticTrees = null
vm.$slots = resolveSlots(vm.$options._renderChildren)
vm._renderContext = vm.$options._parentVnode && vm.$options._parentVnode.context
vm.$slots = resolveSlots(vm.$options._renderChildren, vm._renderContext)
// bind the public createElement fn to this instance
// so that we get proper render context inside it.
vm.$createElement = bind(createElement, vm)
@ -215,7 +216,8 @@ export function renderMixin (Vue: Class<Component>) {
}
export function resolveSlots (
renderChildren: ?VNodeChildren
renderChildren: ?VNodeChildren,
context: ?Component
): { [key: string]: Array<VNode> } {
const slots = {}
if (!renderChildren) {
@ -226,8 +228,10 @@ export function resolveSlots (
let name, child
for (let i = 0, l = children.length; i < l; i++) {
child = children[i]
if (child.data && (name = child.data.slot)) {
delete child.data.slot
// named slots should only be respected if the vnode was rendered in the
// same context.
if (child.context === context &&
child.data && (name = child.data.slot)) {
const slot = (slots[name] || (slots[name] = []))
if (child.tag === 'template') {
slot.push.apply(slot, child.children)

7
src/core/vdom/create-component.js

@ -5,7 +5,8 @@ import VNode from './vnode'
import { normalizeChildren } from './helpers'
import { activeInstance, callHook } from '../instance/lifecycle'
import { resolveSlots } from '../instance/render'
import { warn, isObject, hasOwn, hyphenate, validateProp } from '../util/index'
import { createElement } from './create-element'
import { warn, isObject, hasOwn, hyphenate, validateProp, bind } from '../util/index'
const hooks = { init, prepatch, insert, destroy }
const hooksToMerge = Object.keys(hooks)
@ -101,13 +102,13 @@ function createFunctionalComponent (
}
return Ctor.options.render.call(
null,
context.$createElement,
bind(createElement, { _self: Object.create(context) }),
{
props,
data,
parent: context,
children: normalizeChildren(children),
slots: () => resolveSlots(children)
slots: () => resolveSlots(children, context)
}
)
}

1
test/unit/features/component/component-slot.spec.js

@ -372,6 +372,7 @@ describe('Component slot', () => {
</div>
`
}
const vm = new Vue({
template: '<test><span slot="foo">foo</span></test>',
components: {

Loading…
Cancel
Save