From 684cd7d21aa7cb9a40fb4a8542c4e08fb3801a86 Mon Sep 17 00:00:00 2001 From: Evan You Date: Tue, 12 Sep 2017 21:45:44 -0400 Subject: [PATCH] fix: preserve slot attribute if not resolved by Vue close #6553 --- src/compiler/parser/index.js | 2 ++ src/core/instance/render-helpers/resolve-slots.js | 7 ++++++- test/unit/features/component/component-slot.spec.js | 11 +++++++++++ test/unit/modules/compiler/codegen.spec.js | 2 +- 4 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/compiler/parser/index.js b/src/compiler/parser/index.js index e91bc855b9..eb7fed80d0 100644 --- a/src/compiler/parser/index.js +++ b/src/compiler/parser/index.js @@ -431,6 +431,8 @@ function processSlot (el) { const slotTarget = getBindingAttr(el, 'slot') if (slotTarget) { el.slotTarget = slotTarget === '""' ? '"default"' : slotTarget + // preserve slot as an attribute for native shadow DOM compat + addAttr(el, 'slot', slotTarget) } if (el.tag === 'template') { el.slotScope = getAndRemoveAttr(el, 'scope') diff --git a/src/core/instance/render-helpers/resolve-slots.js b/src/core/instance/render-helpers/resolve-slots.js index 6fe2803040..26ed51d742 100644 --- a/src/core/instance/render-helpers/resolve-slots.js +++ b/src/core/instance/render-helpers/resolve-slots.js @@ -14,10 +14,15 @@ export function resolveSlots ( const defaultSlot = [] for (let i = 0, l = children.length; i < l; i++) { const child = children[i] + const data = child.data + // remove slot attribute if the node is resolved as a Vue slot node + if (data && data.attrs && data.attrs.slot) { + delete data.attrs.slot + } // named slots should only be respected if the vnode was rendered in the // same context. if ((child.context === context || child.functionalContext === context) && - child.data && child.data.slot != null + data && data.slot != null ) { const name = child.data.slot const slot = (slots[name] || (slots[name] = [])) diff --git a/test/unit/features/component/component-slot.spec.js b/test/unit/features/component/component-slot.spec.js index 22e8b2d9ea..66e70dac17 100644 --- a/test/unit/features/component/component-slot.spec.js +++ b/test/unit/features/component/component-slot.spec.js @@ -728,4 +728,15 @@ describe('Component slot', () => { expect(vm.$el.innerHTML).toBe(`
foo
bar
`) }).then(done) }) + + it('should preserve slot attribute if not absorbed by a Vue component', () => { + const vm = new Vue({ + template: ` +
+
+
+ ` + }).$mount() + expect(vm.$el.children[0].getAttribute('slot')).toBe('foo') + }) }) diff --git a/test/unit/modules/compiler/codegen.spec.js b/test/unit/modules/compiler/codegen.spec.js index 8189b52927..37bcf62a76 100644 --- a/test/unit/modules/compiler/codegen.spec.js +++ b/test/unit/modules/compiler/codegen.spec.js @@ -175,7 +175,7 @@ describe('codegen', () => { it('generate slot target', () => { assertCodegen( '

hello world

', - `with(this){return _c('p',{slot:"one"},[_v("hello world")])}` + `with(this){return _c('p',{attrs:{"slot":"one"},slot:"one"},[_v("hello world")])}` ) })