Skip to content

Commit 0a387df

Browse files
fix(sfc/cssVars): fix loss of CSS v-bind variables when setting inline style with string value (#9824)
close #9821
1 parent a6503e3 commit 0a387df

File tree

3 files changed

+41
-0
lines changed

3 files changed

+41
-0
lines changed

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

+31
Original file line numberDiff line numberDiff line change
@@ -293,4 +293,35 @@ describe('useCssVars', () => {
293293
await nextTick()
294294
expect(target.children.length).toBe(0)
295295
})
296+
297+
test('with string style', async () => {
298+
document.body.innerHTML = ''
299+
const state = reactive({ color: 'red' })
300+
const root = document.createElement('div')
301+
const disabled = ref(false)
302+
303+
const App = {
304+
setup() {
305+
useCssVars(() => state)
306+
return () => [
307+
h(
308+
'div',
309+
{ style: disabled.value ? 'pointer-events: none' : undefined },
310+
'foo'
311+
)
312+
]
313+
}
314+
}
315+
render(h(App), root)
316+
await nextTick()
317+
for (const c of [].slice.call(root.children as any)) {
318+
expect((c as HTMLElement).style.getPropertyValue(`--color`)).toBe('red')
319+
}
320+
disabled.value = true
321+
await nextTick()
322+
323+
for (const c of [].slice.call(root.children as any)) {
324+
expect((c as HTMLElement).style.getPropertyValue(`--color`)).toBe('red')
325+
}
326+
})
296327
})

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

+4
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
} from '@vue/runtime-core'
1111
import { ShapeFlags } from '@vue/shared'
1212

13+
export const CSS_VAR_TEXT = Symbol(__DEV__ ? 'CSS_VAR_TEXT' : '')
1314
/**
1415
* Runtime helper for SFC's CSS variable injection feature.
1516
* @private
@@ -79,8 +80,11 @@ function setVarsOnVNode(vnode: VNode, vars: Record<string, string>) {
7980
function setVarsOnNode(el: Node, vars: Record<string, string>) {
8081
if (el.nodeType === 1) {
8182
const style = (el as HTMLElement).style
83+
let cssText = ''
8284
for (const key in vars) {
8385
style.setProperty(`--${key}`, vars[key])
86+
cssText += `--${key}: ${vars[key]};`
8487
}
88+
;(style as any)[CSS_VAR_TEXT] = cssText
8589
}
8690
}

packages/runtime-dom/src/modules/style.ts

+6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { isString, hyphenate, capitalize, isArray } from '@vue/shared'
22
import { camelize, warn } from '@vue/runtime-core'
33
import { vShowOldKey } from '../directives/vShow'
4+
import { CSS_VAR_TEXT } from '../helpers/useCssVars'
45

56
type Style = string | Record<string, string | string[]> | null
67

@@ -22,6 +23,11 @@ export function patchStyle(el: Element, prev: Style, next: Style) {
2223
const currentDisplay = style.display
2324
if (isCssString) {
2425
if (prev !== next) {
26+
// #9821
27+
const cssVarText = (style as any)[CSS_VAR_TEXT]
28+
if (cssVarText) {
29+
;(next as string) += ';' + cssVarText
30+
}
2531
style.cssText = next as string
2632
}
2733
} else if (prev) {

0 commit comments

Comments
 (0)