Skip to content

Commit 8ce3da0

Browse files
committed
feat(portal): support disabled prop
1 parent 039d024 commit 8ce3da0

File tree

5 files changed

+312
-94
lines changed

5 files changed

+312
-94
lines changed

packages/runtime-core/__tests__/components/Portal.spec.ts

+131-8
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import {
88
ref,
99
nextTick
1010
} from '@vue/runtime-test'
11-
import { createVNode } from '../../src/vnode'
11+
import { createVNode, Fragment } from '../../src/vnode'
1212

1313
describe('renderer: portal', () => {
1414
test('should work', () => {
@@ -24,7 +24,7 @@ describe('renderer: portal', () => {
2424
)
2525

2626
expect(serializeInner(root)).toMatchInlineSnapshot(
27-
`"<!--portal--><div>root</div>"`
27+
`"<!--portal start--><!--portal end--><div>root</div>"`
2828
)
2929
expect(serializeInner(target)).toMatchInlineSnapshot(
3030
`"<div>teleported</div>"`
@@ -46,7 +46,7 @@ describe('renderer: portal', () => {
4646
)
4747

4848
expect(serializeInner(root)).toMatchInlineSnapshot(
49-
`"<!--portal--><div>root</div>"`
49+
`"<!--portal start--><!--portal end--><div>root</div>"`
5050
)
5151
expect(serializeInner(targetA)).toMatchInlineSnapshot(
5252
`"<div>teleported</div>"`
@@ -57,7 +57,7 @@ describe('renderer: portal', () => {
5757
await nextTick()
5858

5959
expect(serializeInner(root)).toMatchInlineSnapshot(
60-
`"<!--portal--><div>root</div>"`
60+
`"<!--portal start--><!--portal end--><div>root</div>"`
6161
)
6262
expect(serializeInner(targetA)).toMatchInlineSnapshot(`""`)
6363
expect(serializeInner(targetB)).toMatchInlineSnapshot(
@@ -122,7 +122,7 @@ describe('renderer: portal', () => {
122122
)
123123

124124
expect(serializeInner(root)).toMatchInlineSnapshot(
125-
`"<div><!--portal--><!--portal--></div>"`
125+
`"<div><!--portal start--><!--portal end--><!--portal start--><!--portal end--></div>"`
126126
)
127127
expect(serializeInner(target)).toMatchInlineSnapshot(`"<div>one</div>two"`)
128128

@@ -141,7 +141,7 @@ describe('renderer: portal', () => {
141141
// toggling
142142
render(h('div', [null, h(Portal, { target }, 'three')]), root)
143143
expect(serializeInner(root)).toMatchInlineSnapshot(
144-
`"<div><!----><!--portal--></div>"`
144+
`"<div><!----><!--portal start--><!--portal end--></div>"`
145145
)
146146
expect(serializeInner(target)).toMatchInlineSnapshot(`"three"`)
147147

@@ -154,7 +154,7 @@ describe('renderer: portal', () => {
154154
root
155155
)
156156
expect(serializeInner(root)).toMatchInlineSnapshot(
157-
`"<div><!--portal--><!--portal--></div>"`
157+
`"<div><!--portal start--><!--portal end--><!--portal start--><!--portal end--></div>"`
158158
)
159159
// should append
160160
expect(serializeInner(target)).toMatchInlineSnapshot(
@@ -170,10 +170,133 @@ describe('renderer: portal', () => {
170170
root
171171
)
172172
expect(serializeInner(root)).toMatchInlineSnapshot(
173-
`"<div><!--portal--><!----></div>"`
173+
`"<div><!--portal start--><!--portal end--><!----></div>"`
174174
)
175175
expect(serializeInner(target)).toMatchInlineSnapshot(
176176
`"<div>one</div><div>two</div>"`
177177
)
178178
})
179+
180+
test('disabled', () => {
181+
const target = nodeOps.createElement('div')
182+
const root = nodeOps.createElement('div')
183+
184+
const renderWithDisabled = (disabled: boolean) => {
185+
return h(Fragment, [
186+
h(Portal, { target, disabled }, h('div', 'teleported')),
187+
h('div', 'root')
188+
])
189+
}
190+
191+
render(renderWithDisabled(false), root)
192+
expect(serializeInner(root)).toMatchInlineSnapshot(
193+
`"<!--portal start--><!--portal end--><div>root</div>"`
194+
)
195+
expect(serializeInner(target)).toMatchInlineSnapshot(
196+
`"<div>teleported</div>"`
197+
)
198+
199+
render(renderWithDisabled(true), root)
200+
expect(serializeInner(root)).toMatchInlineSnapshot(
201+
`"<!--portal start--><div>teleported</div><!--portal end--><div>root</div>"`
202+
)
203+
expect(serializeInner(target)).toBe(``)
204+
205+
// toggle back
206+
render(renderWithDisabled(false), root)
207+
expect(serializeInner(root)).toMatchInlineSnapshot(
208+
`"<!--portal start--><!--portal end--><div>root</div>"`
209+
)
210+
expect(serializeInner(target)).toMatchInlineSnapshot(
211+
`"<div>teleported</div>"`
212+
)
213+
})
214+
215+
test('moving portal while enabled', () => {
216+
const target = nodeOps.createElement('div')
217+
const root = nodeOps.createElement('div')
218+
219+
render(
220+
h(Fragment, [
221+
h(Portal, { target }, h('div', 'teleported')),
222+
h('div', 'root')
223+
]),
224+
root
225+
)
226+
expect(serializeInner(root)).toMatchInlineSnapshot(
227+
`"<!--portal start--><!--portal end--><div>root</div>"`
228+
)
229+
expect(serializeInner(target)).toMatchInlineSnapshot(
230+
`"<div>teleported</div>"`
231+
)
232+
233+
render(
234+
h(Fragment, [
235+
h('div', 'root'),
236+
h(Portal, { target }, h('div', 'teleported'))
237+
]),
238+
root
239+
)
240+
expect(serializeInner(root)).toMatchInlineSnapshot(
241+
`"<div>root</div><!--portal start--><!--portal end-->"`
242+
)
243+
expect(serializeInner(target)).toMatchInlineSnapshot(
244+
`"<div>teleported</div>"`
245+
)
246+
247+
render(
248+
h(Fragment, [
249+
h(Portal, { target }, h('div', 'teleported')),
250+
h('div', 'root')
251+
]),
252+
root
253+
)
254+
expect(serializeInner(root)).toMatchInlineSnapshot(
255+
`"<!--portal start--><!--portal end--><div>root</div>"`
256+
)
257+
expect(serializeInner(target)).toMatchInlineSnapshot(
258+
`"<div>teleported</div>"`
259+
)
260+
})
261+
262+
test('moving portal while disabled', () => {
263+
const target = nodeOps.createElement('div')
264+
const root = nodeOps.createElement('div')
265+
266+
render(
267+
h(Fragment, [
268+
h(Portal, { target, disabled: true }, h('div', 'teleported')),
269+
h('div', 'root')
270+
]),
271+
root
272+
)
273+
expect(serializeInner(root)).toMatchInlineSnapshot(
274+
`"<!--portal start--><div>teleported</div><!--portal end--><div>root</div>"`
275+
)
276+
expect(serializeInner(target)).toBe('')
277+
278+
render(
279+
h(Fragment, [
280+
h('div', 'root'),
281+
h(Portal, { target, disabled: true }, h('div', 'teleported'))
282+
]),
283+
root
284+
)
285+
expect(serializeInner(root)).toMatchInlineSnapshot(
286+
`"<div>root</div><!--portal start--><div>teleported</div><!--portal end-->"`
287+
)
288+
expect(serializeInner(target)).toBe('')
289+
290+
render(
291+
h(Fragment, [
292+
h(Portal, { target, disabled: true }, h('div', 'teleported')),
293+
h('div', 'root')
294+
]),
295+
root
296+
)
297+
expect(serializeInner(root)).toMatchInlineSnapshot(
298+
`"<!--portal start--><div>teleported</div><!--portal end--><div>root</div>"`
299+
)
300+
expect(serializeInner(target)).toBe('')
301+
})
179302
})

packages/runtime-core/src/components/KeepAlive.ts

-1
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,6 @@ const KeepAliveImpl = {
206206
if (cachedVNode) {
207207
// copy over mounted state
208208
vnode.el = cachedVNode.el
209-
vnode.anchor = cachedVNode.anchor
210209
vnode.component = cachedVNode.component
211210
if (vnode.transition) {
212211
// recursively update transition hooks on subTree

0 commit comments

Comments
 (0)