From b8d329dafea98766a8a419fa1c38ccc1ae449429 Mon Sep 17 00:00:00 2001 From: daiwei Date: Sat, 29 May 2021 15:10:50 +0800 Subject: [PATCH] fix(runtime-dom): useCssVars work with createStaticVNode chore: improve code chore: improve code --- .../__tests__/helpers/useCssVars.spec.ts | 23 +++++++++++++++++++ .../runtime-dom/src/helpers/useCssVars.ts | 21 +++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/packages/runtime-dom/__tests__/helpers/useCssVars.spec.ts b/packages/runtime-dom/__tests__/helpers/useCssVars.spec.ts index ae86e57ba5d..a72d0a9c2df 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 82c48e33a04..e6fd33e3174 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' @@ -53,5 +54,25 @@ function setVarsOnVNode(vnode: VNode, vars: Record) { } } else if (vnode.type === Fragment) { ;(vnode.children as VNode[]).forEach(c => setVarsOnVNode(c, vars)) + } else if (vnode.type === Static) { + const { el, anchor } = vnode + let current: HTMLElement | null = el as HTMLElement + while (current) { + setVarsOnElement(current, vars) + if (current === anchor) break + current = current.nextSibling as HTMLElement + } + } + + function setVarsOnElement(el: HTMLElement, vars: Record) { + const style = el.style + for (const key in vars) { + style.setProperty(`--${key}`, vars[key]) + } + + for (var i = 0; i < el.children.length; i++) { + const n = el.children[i] + setVarsOnElement(n as HTMLElement, vars) + } } }