diff --git a/src/core/vdom/create-element.js b/src/core/vdom/create-element.js index ba36e15b12d..f8bb5f0413a 100644 --- a/src/core/vdom/create-element.js +++ b/src/core/vdom/create-element.js @@ -151,6 +151,17 @@ function applyNS (vnode, ns, force) { } } } + + // #11315 + if (isObject(vnode.componentOptions) && isDef(vnode.componentOptions.children)) { + for (var i = 0, l = vnode.componentOptions.children.length; i < l; i++) { + var child = vnode.componentOptions.children[i] + if (isDef(child.tag) && ( + isUndef(child.ns) || (isTrue(force) && child.tag !== 'svg'))) { + applyNS(child, ns, force) + } + } + } } // ref #5318 diff --git a/test/unit/modules/vdom/create-element.spec.js b/test/unit/modules/vdom/create-element.spec.js index 68773850be7..1212cdc95ff 100644 --- a/test/unit/modules/vdom/create-element.spec.js +++ b/test/unit/modules/vdom/create-element.spec.js @@ -143,6 +143,49 @@ describe('create-element', () => { expect(vnode.children[0].children[1].ns).toBe('svg') }) + // #11315 + it('render svg foreignObject nested component slot with correct namespace', () => { + const vm = new Vue({ + template: ` + + + + `, + components: { + 'box': { + template: ` + + +

+
+
+ `, + components: { + 'comp-with-slot': { + template: ` +
+ +
+ ` + } + } + } + } + }).$mount() + const box = vm.$children[0] + const compWithSlot = box.$children[0] + expect(box.$vnode.ns).toBe('svg') + expect(box._vnode.tag).toBe('foreignObject') + expect(box._vnode.ns).toBe('svg') + expect(compWithSlot.$vnode.ns).toBeUndefined() + expect(compWithSlot._vnode.tag).toBe('div') + expect(compWithSlot._vnode.ns).toBeUndefined() + expect(compWithSlot._vnode.children[0].tag).toBe('p') + expect(compWithSlot._vnode.children[0].ns).toBeUndefined() + expect(compWithSlot._vnode.children[1].tag).toBe('svg') + expect(compWithSlot._vnode.children[1].ns).toBe('svg') + }) + // #6642 it('render svg foreignObject component with correct namespace', () => { const vm = new Vue({