Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(runtime-dom): cssvars correctly handles async components #8523

Merged
merged 10 commits into from
Apr 15, 2024
57 changes: 57 additions & 0 deletions packages/runtime-dom/__tests__/helpers/useCssVars.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,63 @@ describe('useCssVars', () => {
}
})

test('with v-if & async component & suspense', async () => {
const state = reactive({ color: 'red' })
const root = document.createElement('div')
const show = ref(false)
let resolveAsync: any
let asyncPromise: any

const AsyncComp = {
setup() {
useCssVars(() => state)
asyncPromise = new Promise(r => {
resolveAsync = () => {
r(() => h('p', 'default'))
}
})
return asyncPromise
}
}

const App = {
setup() {
return () =>
h(Suspense, null, {
default: h('div', {}, show.value ? h(AsyncComp) : h('p'))
})
}
}

render(h(App), root)
await nextTick()
// AsyncComp resolve
show.value = true
await nextTick()
resolveAsync()
await asyncPromise.then(() => {})
// Suspense effects flush
await nextTick()
// css vars use with default tree
for (const c of [].slice.call(root.children as any)) {
expect(
((c as any).children[0] as HTMLElement).style.getPropertyValue(
`--color`
)
).toBe(`red`)
}

state.color = 'green'
await nextTick()
for (const c of [].slice.call(root.children as any)) {
expect(
((c as any).children[0] as HTMLElement).style.getPropertyValue(
`--color`
)
).toBe('green')
}
})

test('with subTree changed', async () => {
const state = reactive({ color: 'red' })
const value = ref(true)
Expand Down
13 changes: 10 additions & 3 deletions packages/runtime-dom/src/helpers/useCssVars.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,16 @@ export function useCssVars(getter: (ctx: any) => Record<string, string>) {
})

const setVars = () => {
const vars = getter(instance.proxy)
setVarsOnVNode(instance.subTree, vars)
updateTeleports(vars)
// #8520
if (!instance.asyncResolved && instance.asyncDep && __FEATURE_SUSPENSE__) {
instance.asyncDep.then(() => {
watchPostEffect(setVars)
})
} else {
const vars = getter(instance.proxy)
setVarsOnVNode(instance.subTree, vars)
updateTeleports(vars)
}
}

watchPostEffect(setVars)
Expand Down
Loading