Skip to content

Commit 6a0c7cd

Browse files
authored
fix(sfc): fix style variables injection on static vnode (#3847)
fix #3841
1 parent 03e2684 commit 6a0c7cd

File tree

2 files changed

+40
-3
lines changed

2 files changed

+40
-3
lines changed

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

+23
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import {
22
ref,
33
render,
44
useCssVars,
5+
createStaticVNode,
56
h,
67
reactive,
78
nextTick,
@@ -140,4 +141,26 @@ describe('useCssVars', () => {
140141
expect((c as HTMLElement).style.getPropertyValue(`--color`)).toBe('red')
141142
}
142143
})
144+
145+
test('with createStaticVNode', async () => {
146+
const state = reactive({ color: 'red' })
147+
const root = document.createElement('div')
148+
149+
const App = {
150+
setup() {
151+
useCssVars(() => state)
152+
return () => [
153+
h('div'),
154+
createStaticVNode('<div>1</div><div><span>2</span></div>', 2),
155+
h('div')
156+
]
157+
}
158+
}
159+
160+
render(h(App), root)
161+
await nextTick()
162+
for (const c of [].slice.call(root.children as any)) {
163+
expect((c as HTMLElement).style.getPropertyValue(`--color`)).toBe('red')
164+
}
165+
})
143166
})

packages/runtime-dom/src/helpers/useCssVars.ts

+17-3
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {
44
warn,
55
VNode,
66
Fragment,
7+
Static,
78
onUpdated,
89
watchEffect
910
} from '@vue/runtime-core'
@@ -47,11 +48,24 @@ function setVarsOnVNode(vnode: VNode, vars: Record<string, string>) {
4748
}
4849

4950
if (vnode.shapeFlag & ShapeFlags.ELEMENT && vnode.el) {
50-
const style = vnode.el.style
51+
setVarsOnNode(vnode.el as Node, vars)
52+
} else if (vnode.type === Fragment) {
53+
;(vnode.children as VNode[]).forEach(c => setVarsOnVNode(c, vars))
54+
} else if (vnode.type === Static) {
55+
let { el, anchor } = vnode
56+
while (el) {
57+
setVarsOnNode(el as Node, vars)
58+
if (el === anchor) break
59+
el = el.nextSibling
60+
}
61+
}
62+
}
63+
64+
function setVarsOnNode(el: Node, vars: Record<string, string>) {
65+
if (el.nodeType === 1) {
66+
const style = (el as HTMLElement).style
5167
for (const key in vars) {
5268
style.setProperty(`--${key}`, vars[key])
5369
}
54-
} else if (vnode.type === Fragment) {
55-
;(vnode.children as VNode[]).forEach(c => setVarsOnVNode(c, vars))
5670
}
5771
}

0 commit comments

Comments
 (0)