diff --git a/src/core/vdom/vnode.js b/src/core/vdom/vnode.js index 0e3e2e9e63..bdc17e9f97 100644 --- a/src/core/vdom/vnode.js +++ b/src/core/vdom/vnode.js @@ -90,7 +90,10 @@ export function cloneVNode (vnode: VNode): VNode { const cloned = new VNode( vnode.tag, vnode.data, - vnode.children, + // #7975 + // clone children array to avoid mutating original in case of cloning + // a child. + vnode.children && vnode.children.slice(), vnode.text, vnode.elm, vnode.context, diff --git a/test/unit/features/component/component-slot.spec.js b/test/unit/features/component/component-slot.spec.js index e667a46ef8..75b5254601 100644 --- a/test/unit/features/component/component-slot.spec.js +++ b/test/unit/features/component/component-slot.spec.js @@ -886,4 +886,58 @@ describe('Component slot', () => { expect(vm.$el.textContent).toBe('foo') }).then(done) }) + + // #7975 + it('should update named slot correctly when its position in the tree changed', done => { + const ChildComponent = { + template: '{{ message }}', + props: ['message'] + } + let parentVm + const ParentComponent = { + template: ` +
+ + + + + + +
+ `, + data () { + return { + alter: true + } + }, + mounted () { + parentVm = this + } + } + const vm = new Vue({ + template: ` + + + + + + `, + components: { + ChildComponent, + ParentComponent + }, + data () { + return { + message: 1 + } + } + }).$mount() + expect(vm.$el.firstChild.innerHTML).toBe('1') + parentVm.alter = false + waitForUpdate(() => { + vm.message = 2 + }).then(() => { + expect(vm.$el.firstChild.innerHTML).toBe('2') + }).then(done) + }) })