Skip to content

Commit cfb5bef

Browse files
committed
fix: ensure updateCssVars is called when subtree changed
1 parent c594f27 commit cfb5bef

File tree

5 files changed

+34
-9
lines changed

5 files changed

+34
-9
lines changed

packages/runtime-vapor/__tests__/helpers/useCssVars.spec.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -270,8 +270,7 @@ describe('useVaporCssVars', () => {
270270
expect(target.children.length).toBe(2)
271271
for (const c of [].slice.call(target.children as any)) {
272272
expect((c as HTMLElement).style.getPropertyValue(`--color`)).toBe('red')
273-
// TODO: problem is slot updateCssVars not called when slot changes
274-
// expect((c as HTMLElement).outerHTML.includes('data-v-owner')).toBe(true)
273+
expect((c as HTMLElement).outerHTML.includes('data-v-owner')).toBe(true)
275274
}
276275
})
277276

packages/runtime-vapor/src/apiCreateFor.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,7 @@ export const createFor = (
402402
} else {
403403
oldBlocks = []
404404
}
405+
if (frag.effects) frag.effects.forEach(effect => effect())
405406
setActiveSub(prevSub)
406407
}
407408

packages/runtime-vapor/src/components/Teleport.ts

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import {
2121
import { rawPropsProxyHandlers } from '../componentProps'
2222
import { renderEffect } from '../renderEffect'
2323
import { extend, isArray } from '@vue/shared'
24-
import { VaporFragment } from '../fragment'
24+
import { VaporFragment, isFragment } from '../fragment'
2525
import {
2626
advanceHydrationNode,
2727
currentHydrationNode,
@@ -48,6 +48,7 @@ export class TeleportFragment extends VaporFragment {
4848
private rawProps?: LooseRawProps
4949
private resolvedProps?: TeleportProps
5050
private rawSlots?: LooseRawSlots
51+
isDisabled?: boolean
5152

5253
target?: ParentNode | null
5354
targetAnchor?: Node | null
@@ -78,6 +79,7 @@ export class TeleportFragment extends VaporFragment {
7879
rawPropsProxyHandlers,
7980
) as any as TeleportProps,
8081
)
82+
this.isDisabled = isTeleportDisabled(this.resolvedProps!)
8183
this.handlePropsUpdate()
8284
})
8385

@@ -97,8 +99,24 @@ export class TeleportFragment extends VaporFragment {
9799
)
98100
})
99101

102+
const nodes = this.nodes
103+
// register updateCssVars to sub fragments's effects so that
104+
// updateCssVars will be called when subtree changed
105+
if (this.parentComponent && this.parentComponent.ut) {
106+
if (isFragment(nodes)) {
107+
;(nodes.effects || (nodes.effects = [])).push(() => updateCssVars(this))
108+
} else if (isArray(nodes)) {
109+
nodes.forEach(node => {
110+
if (isFragment(node)) {
111+
;(node.effects || (node.effects = [])).push(() =>
112+
updateCssVars(this),
113+
)
114+
}
115+
})
116+
}
117+
}
118+
100119
if (__DEV__) {
101-
const nodes = this.nodes
102120
if (isVaporComponent(nodes)) {
103121
nodes.parentTeleport = this
104122
} else if (isArray(nodes)) {
@@ -162,7 +180,7 @@ export class TeleportFragment extends VaporFragment {
162180
}
163181

164182
mount(target, this.targetAnchor!)
165-
updateCssVars(this, false)
183+
updateCssVars(this)
166184
} else if (__DEV__) {
167185
warn(
168186
`Invalid Teleport target on ${this.targetAnchor ? 'update' : 'mount'}:`,
@@ -173,9 +191,9 @@ export class TeleportFragment extends VaporFragment {
173191
}
174192

175193
// mount into main container
176-
if (isTeleportDisabled(this.resolvedProps!)) {
194+
if (this.isDisabled) {
177195
mount(this.parent, this.anchor!)
178-
updateCssVars(this, true)
196+
updateCssVars(this)
179197
}
180198
// mount into target container
181199
else {
@@ -333,11 +351,11 @@ function locateTeleportEndAnchor(
333351
return null
334352
}
335353

336-
function updateCssVars(frag: TeleportFragment, isDisabled: boolean) {
354+
function updateCssVars(frag: TeleportFragment) {
337355
const ctx = frag.parentComponent as GenericComponentInstance
338356
if (ctx && ctx.ut) {
339357
let node, anchor
340-
if (isDisabled) {
358+
if (frag.isDisabled) {
341359
node = frag.placeholder
342360
anchor = frag.anchor
343361
} else {

packages/runtime-vapor/src/fragment.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,9 @@ export class VaporFragment<T extends Block = Block>
5656
refKey: string | undefined,
5757
) => void
5858

59+
// effects to run after fragment render
60+
effects?: (() => void)[]
61+
5962
constructor(nodes: T) {
6063
this.nodes = nodes
6164
}
@@ -185,6 +188,7 @@ export class DynamicFragment extends VaporFragment {
185188
this.scope = undefined
186189
this.nodes = []
187190
}
191+
if (this.effects) this.effects.forEach(effect => effect())
188192
}
189193

190194
hydrate = (isEmpty = false): void => {

packages/runtime-vapor/src/vdomInterop.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,7 @@ function createVDOMComponent(
380380
}
381381

382382
frag.nodes = vnode.el as any
383+
if (frag.effects) frag.effects.forEach(effect => effect())
383384
}
384385

385386
frag.remove = unmount
@@ -445,6 +446,8 @@ function renderVDOMSlot(
445446
internals.um(oldVNode, parentComponent as any, null)
446447
}
447448
}
449+
450+
if (frag.effects) frag.effects.forEach(effect => effect())
448451
}
449452

450453
const render = (parentNode?: ParentNode, anchor?: Node | null) => {

0 commit comments

Comments
 (0)