fix(sfc): fix style variables injection on static vnode (#3847)
fix #3841
This commit is contained in:
parent
03e26845e2
commit
6a0c7cd905
@ -2,6 +2,7 @@ import {
|
|||||||
ref,
|
ref,
|
||||||
render,
|
render,
|
||||||
useCssVars,
|
useCssVars,
|
||||||
|
createStaticVNode,
|
||||||
h,
|
h,
|
||||||
reactive,
|
reactive,
|
||||||
nextTick,
|
nextTick,
|
||||||
@ -140,4 +141,26 @@ describe('useCssVars', () => {
|
|||||||
expect((c as HTMLElement).style.getPropertyValue(`--color`)).toBe('red')
|
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('<div>1</div><div><span>2</span></div>', 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')
|
||||||
|
}
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
@ -4,6 +4,7 @@ import {
|
|||||||
warn,
|
warn,
|
||||||
VNode,
|
VNode,
|
||||||
Fragment,
|
Fragment,
|
||||||
|
Static,
|
||||||
onUpdated,
|
onUpdated,
|
||||||
watchEffect
|
watchEffect
|
||||||
} from '@vue/runtime-core'
|
} from '@vue/runtime-core'
|
||||||
@ -47,11 +48,24 @@ function setVarsOnVNode(vnode: VNode, vars: Record<string, string>) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (vnode.shapeFlag & ShapeFlags.ELEMENT && vnode.el) {
|
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<string, string>) {
|
||||||
|
if (el.nodeType === 1) {
|
||||||
|
const style = (el as HTMLElement).style
|
||||||
for (const key in vars) {
|
for (const key in vars) {
|
||||||
style.setProperty(`--${key}`, vars[key])
|
style.setProperty(`--${key}`, vars[key])
|
||||||
}
|
}
|
||||||
} else if (vnode.type === Fragment) {
|
|
||||||
;(vnode.children as VNode[]).forEach(c => setVarsOnVNode(c, vars))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user