diff --git a/packages/runtime-dom/__tests__/helpers/useCssVars.spec.ts b/packages/runtime-dom/__tests__/helpers/useCssVars.spec.ts index ae86e57ba..a72d0a9c2 100644 --- a/packages/runtime-dom/__tests__/helpers/useCssVars.spec.ts +++ b/packages/runtime-dom/__tests__/helpers/useCssVars.spec.ts @@ -2,6 +2,7 @@ import { ref, render, useCssVars, + createStaticVNode, h, reactive, nextTick, @@ -140,4 +141,26 @@ describe('useCssVars', () => { expect((c as HTMLElement).style.getPropertyValue(`--color`)).toBe('red') } }) + + test('with createStaticVNode', async () => { + const state = reactive({ color: 'red' }) + const root = document.createElement('div') + + const App = { + setup() { + useCssVars(() => state) + return () => [ + h('div'), + createStaticVNode('
1
2
', 2), + h('div') + ] + } + } + + render(h(App), root) + await nextTick() + for (const c of [].slice.call(root.children as any)) { + expect((c as HTMLElement).style.getPropertyValue(`--color`)).toBe('red') + } + }) }) diff --git a/packages/runtime-dom/src/helpers/useCssVars.ts b/packages/runtime-dom/src/helpers/useCssVars.ts index 82c48e33a..3253dd227 100644 --- a/packages/runtime-dom/src/helpers/useCssVars.ts +++ b/packages/runtime-dom/src/helpers/useCssVars.ts @@ -4,6 +4,7 @@ import { warn, VNode, Fragment, + Static, onUpdated, watchEffect } from '@vue/runtime-core' @@ -47,11 +48,24 @@ function setVarsOnVNode(vnode: VNode, vars: Record) { } if (vnode.shapeFlag & ShapeFlags.ELEMENT && vnode.el) { - const style = vnode.el.style + setVarsOnNode(vnode.el as Node, vars) + } else if (vnode.type === Fragment) { + ;(vnode.children as VNode[]).forEach(c => setVarsOnVNode(c, vars)) + } else if (vnode.type === Static) { + let { el, anchor } = vnode + while (el) { + setVarsOnNode(el as Node, vars) + if (el === anchor) break + el = el.nextSibling + } + } +} + +function setVarsOnNode(el: Node, vars: Record) { + if (el.nodeType === 1) { + const style = (el as HTMLElement).style for (const key in vars) { style.setProperty(`--${key}`, vars[key]) } - } else if (vnode.type === Fragment) { - ;(vnode.children as VNode[]).forEach(c => setVarsOnVNode(c, vars)) } }