Skip to content

Commit 6a3e771

Browse files
committed
test: add test
1 parent 9f51f13 commit 6a3e771

File tree

3 files changed

+101
-9
lines changed

3 files changed

+101
-9
lines changed

packages/runtime-core/src/renderer.ts

+1-3
Original file line numberDiff line numberDiff line change
@@ -966,9 +966,7 @@ function baseCreateRenderer(
966966
!isSameVNodeType(oldVNode, newVNode) ||
967967
// - In the case of a component, it could contain anything.
968968
oldVNode.shapeFlag & (ShapeFlags.COMPONENT | ShapeFlags.TELEPORT))
969-
? oldVNode.el._parentNode && !oldVNode.el.isConnected
970-
? oldVNode.el._parentNode
971-
: hostParentNode(oldVNode.el)!
969+
? hostParentNode(oldVNode.el) || oldVNode.el._parentNode
972970
: // In other cases, the parent container is not actually used so we
973971
// just pass the block element here to avoid a DOM parentNode call.
974972
fallbackContainer

packages/runtime-dom/__tests__/customElement.spec.ts

+93-5
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ import {
99
createCommentVNode,
1010
createElementBlock,
1111
createElementVNode,
12+
createSlots,
13+
createTextVNode,
1214
defineAsyncComponent,
1315
defineComponent,
1416
defineCustomElement,
@@ -1138,8 +1140,8 @@ describe('defineCustomElement', () => {
11381140
app.unmount()
11391141
})
11401142

1141-
//#13206
1142-
test('should update slotted children correctly w/ shadowRoot false', async () => {
1143+
// #13206
1144+
test('update slotted v-if nodes w/ shadowRoot false', async () => {
11431145
const E = defineCustomElement(
11441146
defineComponent({
11451147
props: {
@@ -1148,7 +1150,7 @@ describe('defineCustomElement', () => {
11481150
render() {
11491151
return this.isShown
11501152
? h('div', { key: 0 }, [renderSlot(this.$slots, 'default')])
1151-
: null
1153+
: createCommentVNode('v-if')
11521154
},
11531155
}),
11541156
{ shadowRoot: false },
@@ -1202,7 +1204,7 @@ describe('defineCustomElement', () => {
12021204
const app = createApp(App)
12031205
app.mount(container)
12041206
expect(container.innerHTML).toBe(
1205-
`<ce-shadow-root-false data-v-app=""><!----></ce-shadow-root-false>`,
1207+
`<ce-shadow-root-false data-v-app=""><!--v-if--></ce-shadow-root-false>`,
12061208
)
12071209

12081210
click()
@@ -1214,7 +1216,7 @@ describe('defineCustomElement', () => {
12141216
click()
12151217
await nextTick()
12161218
expect(container.innerHTML).toBe(
1217-
`<ce-shadow-root-false data-v-app=""><!----></ce-shadow-root-false>`,
1219+
`<ce-shadow-root-false data-v-app=""><!--v-if--></ce-shadow-root-false>`,
12181220
)
12191221

12201222
click()
@@ -1223,6 +1225,92 @@ describe('defineCustomElement', () => {
12231225
`<ce-shadow-root-false data-v-app="" is-shown=""><div><div>true</div><div>hi</div></div></ce-shadow-root-false>`,
12241226
)
12251227
})
1228+
1229+
// #13234
1230+
test('switch between slotted and fallback nodes w/ shadowRoot false', async () => {
1231+
const E = defineCustomElement(
1232+
defineComponent({
1233+
render() {
1234+
return renderSlot(this.$slots, 'foo', {}, () => [
1235+
createTextVNode('fallback'),
1236+
])
1237+
},
1238+
}),
1239+
{ shadowRoot: false },
1240+
)
1241+
customElements.define('ce-with-fallback-shadow-root-false', E)
1242+
1243+
const Comp = defineComponent({
1244+
render() {
1245+
return (
1246+
openBlock(),
1247+
createElementBlock('ce-with-fallback-shadow-root-false', null, [
1248+
this.$slots.foo
1249+
? (openBlock(),
1250+
createElementBlock('div', { key: 0, slot: 'foo' }, [
1251+
renderSlot(this.$slots, 'foo'),
1252+
]))
1253+
: createCommentVNode('v-if', true),
1254+
renderSlot(this.$slots, 'default'),
1255+
])
1256+
)
1257+
},
1258+
})
1259+
1260+
const isShown = ref(false)
1261+
const App = defineComponent({
1262+
components: { Comp },
1263+
render() {
1264+
return (
1265+
openBlock(),
1266+
createBlock(
1267+
Comp,
1268+
null,
1269+
createSlots(
1270+
{ _: 2 /* DYNAMIC */ } as any,
1271+
[
1272+
isShown.value
1273+
? {
1274+
name: 'foo',
1275+
fn: withCtx(() => [createTextVNode('foo')]),
1276+
key: '0',
1277+
}
1278+
: undefined,
1279+
] as any,
1280+
),
1281+
1024 /* DYNAMIC_SLOTS */,
1282+
)
1283+
)
1284+
},
1285+
})
1286+
1287+
const container = document.createElement('div')
1288+
document.body.appendChild(container)
1289+
1290+
const app = createApp(App)
1291+
app.mount(container)
1292+
expect(container.innerHTML).toBe(
1293+
`<ce-with-fallback-shadow-root-false data-v-app="">` +
1294+
`fallback` +
1295+
`</ce-with-fallback-shadow-root-false>`,
1296+
)
1297+
1298+
isShown.value = true
1299+
await nextTick()
1300+
expect(container.innerHTML).toBe(
1301+
`<ce-with-fallback-shadow-root-false data-v-app="">` +
1302+
`<div slot="foo">foo</div>` +
1303+
`</ce-with-fallback-shadow-root-false>`,
1304+
)
1305+
1306+
isShown.value = false
1307+
await nextTick()
1308+
expect(container.innerHTML).toBe(
1309+
`<ce-with-fallback-shadow-root-false data-v-app="">` +
1310+
`fallback<!--v-if-->` +
1311+
`</ce-with-fallback-shadow-root-false>`,
1312+
)
1313+
})
12261314
})
12271315

12281316
describe('helpers', () => {

packages/runtime-dom/src/apiCustomElement.ts

+7-1
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,9 @@ export class VueElement
337337
this._app && this._app.unmount()
338338
if (this._instance) this._instance.ce = undefined
339339
this._app = this._instance = null
340+
this._slots = undefined
341+
this._slotFallbacks = undefined
342+
this._slotAnchors = undefined
340343
}
341344
})
342345
}
@@ -692,7 +695,10 @@ export class VueElement
692695
for (let i = 0; i < prevNodes.length; i++) {
693696
const prevNode = prevNodes[i]
694697
const newNode = newNodes[i]
695-
if (isComment(prevNode, 'v-if') || isComment(newNode, 'v-if')) {
698+
if (
699+
prevNode !== newNode &&
700+
(isComment(prevNode, 'v-if') || isComment(newNode, 'v-if'))
701+
) {
696702
Object.keys(this._slots!).forEach(name => {
697703
const slotNodes = this._slots![name]
698704
if (slotNodes) {

0 commit comments

Comments
 (0)