Browse Source

fix: preserve slot attribute if not resolved by Vue

close #6553
Evan You 8 years ago
parent
commit
684cd7d21a

+ 2 - 0
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')

+ 6 - 1
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] = []))

+ 11 - 0
test/unit/features/component/component-slot.spec.js

@@ -728,4 +728,15 @@ describe('Component slot', () => {
       expect(vm.$el.innerHTML).toBe(`<i><div><div>foo</div></div><div>bar</div></i>`)
     }).then(done)
   })
+
+  it('should preserve slot attribute if not absorbed by a Vue component', () => {
+    const vm = new Vue({
+      template: `
+        <div>
+          <div slot="foo"></div>
+        </div>
+      `
+    }).$mount()
+    expect(vm.$el.children[0].getAttribute('slot')).toBe('foo')
+  })
 })

+ 1 - 1
test/unit/modules/compiler/codegen.spec.js

@@ -175,7 +175,7 @@ describe('codegen', () => {
   it('generate slot target', () => {
     assertCodegen(
       '<p slot="one">hello world</p>',
-      `with(this){return _c('p',{slot:"one"},[_v("hello world")])}`
+      `with(this){return _c('p',{attrs:{"slot":"one"},slot:"one"},[_v("hello world")])}`
     )
   })