diff --git a/src/compiler/codegen/index.ts b/src/compiler/codegen/index.ts index b0daf352f82..1d972a4d65b 100644 --- a/src/compiler/codegen/index.ts +++ b/src/compiler/codegen/index.ts @@ -432,7 +432,7 @@ function genScopedSlots( // it's possible for the same component to be reused but with different // compiled slot content. To avoid that, we generate a unique key based on // the generated code of all the slot contents. - let needsKey = !!el.if + let needsKey = !!(el.if || el.elseif || el.else) // OR when it is inside another scoped slot or v-for (the reactivity may be // disconnected due to the intermediate scope variable) @@ -449,7 +449,7 @@ function genScopedSlots( needsForceUpdate = true break } - if (parent.if) { + if (parent.if || parent.elseif) { needsKey = true } parent = parent.parent diff --git a/test/unit/features/component/component-scoped-slot.spec.ts b/test/unit/features/component/component-scoped-slot.spec.ts index 96c23f8c66c..d8ff48db253 100644 --- a/test/unit/features/component/component-scoped-slot.spec.ts +++ b/test/unit/features/component/component-scoped-slot.spec.ts @@ -1267,7 +1267,7 @@ describe('Component scoped slot', () => { }).then(done) }) - // #9534 + // #9534 #12922 it('should detect conditional reuse with different slot content', done => { const Foo = { template: `
` @@ -1276,25 +1276,44 @@ describe('Component scoped slot', () => { const vm = new Vue({ components: { Foo }, data: { - ok: true + value: 'a' }, template: `
-
+
{{ n }}
-
+
{{ n + 1 }}
+
+ {{ n + 2 }} +
+
+ {{ n + 3 }} +
` }).$mount() expect(vm.$el.textContent.trim()).toBe(`1`) - vm.ok = false + vm.value = 'b' waitForUpdate(() => { expect(vm.$el.textContent.trim()).toBe(`2`) - }).then(done) + }) + .then(() => { + vm.value = 'c' + }) + .then(() => { + expect(vm.$el.textContent.trim()).toBe(`3`) + }) + .then(() => { + vm.value = 'd' + }) + .then(() => { + expect(vm.$el.textContent.trim()).toBe(`4`) + }) + .then(done) }) // #9644 @@ -1403,4 +1422,42 @@ describe('Component scoped slot', () => { expect(parent.$el.textContent).toMatch(``) }).then(done) }) + // #12223 + it('should update when switching between components with slot', done => { + const Foo = { + template: `
` + } + + const vm = new Vue({ + template: `
+ + + + +
`, + data: { + value: 'a' + }, + components: { Foo } + }).$mount() + + expect(vm.$el.textContent.trim()).toBe(`1`) + vm.value = 'b' + waitForUpdate(() => { + expect(vm.$el.textContent.trim()).toBe(`2`) + }) + .then(() => { + vm.value = 'c' + }) + .then(() => { + expect(vm.$el.textContent.trim()).toBe(`3`) + }) + .then(() => { + vm.value = 'd' + }) + .then(() => { + expect(vm.$el.textContent.trim()).toBe(`4`) + }) + .then(done) + }) })