ソースを参照

adjust named slot resolve check (fix #3819)

Evan You 9 年 前
コミット
99ea0f8229

+ 1 - 1
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;

+ 1 - 1
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()
     }
   }

+ 8 - 4
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)

+ 4 - 3
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 - 0
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: {