From 82a7559d4917d956b2ef249fa7fb8f7cadfc1587 Mon Sep 17 00:00:00 2001 From: yangchangtao Date: Wed, 20 Nov 2024 10:55:10 +0800 Subject: [PATCH 1/8] fix: . --- packages/runtime-core/src/hydration.ts | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/packages/runtime-core/src/hydration.ts b/packages/runtime-core/src/hydration.ts index a94ff356810..73b87def6a7 100644 --- a/packages/runtime-core/src/hydration.ts +++ b/packages/runtime-core/src/hydration.ts @@ -938,10 +938,13 @@ function resolveCssVars( ) { const cssVars = instance.getCssVars() for (const key in cssVars) { - expectedMap.set( - `--${getEscapedCssVarName(key, false)}`, - String(cssVars[key]), - ) + const value = cssVars[key] + if (isString(value) || typeof value === 'number') { + expectedMap.set( + `--${getEscapedCssVarName(key, false)}`, + String(cssVars[key]), + ) + } } } if (vnode === root && instance.parent) { From c12af5da945ae63e068fe1b624e9698ebc74427f Mon Sep 17 00:00:00 2001 From: yangchangtao Date: Wed, 20 Nov 2024 11:01:16 +0800 Subject: [PATCH 2/8] test: add testcase --- .../runtime-core/__tests__/hydration.spec.ts | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/packages/runtime-core/__tests__/hydration.spec.ts b/packages/runtime-core/__tests__/hydration.spec.ts index 56011d06359..b98a8af91e5 100644 --- a/packages/runtime-core/__tests__/hydration.spec.ts +++ b/packages/runtime-core/__tests__/hydration.spec.ts @@ -2204,6 +2204,27 @@ describe('SSR hydration', () => { app.mount(container) expect(`Hydration style mismatch`).not.toHaveBeenWarned() }) + + test('should not warn on css v-bind non-string and number value', () => { + const container = document.createElement('div') + container.innerHTML = `
` + const app = createSSRApp({ + setup() { + const backGroundColor = ref(null) + useCssVars(() => ({ + 'foo.bar': backGroundColor.value, + })) + return () => h(Child) + }, + }) + const Child = { + setup() { + return () => h('div', { style: 'padding: 4px' }) + }, + } + app.mount(container) + expect(`Hydration style mismatch`).not.toHaveBeenWarned() + }) }) describe('data-allow-mismatch', () => { From 95738bb8cd379365b3af8f34a8867c4e9e282a5e Mon Sep 17 00:00:00 2001 From: yangchangtao Date: Wed, 20 Nov 2024 11:02:40 +0800 Subject: [PATCH 3/8] chore: update --- packages/runtime-core/src/hydration.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/packages/runtime-core/src/hydration.ts b/packages/runtime-core/src/hydration.ts index 73b87def6a7..7c11c01faea 100644 --- a/packages/runtime-core/src/hydration.ts +++ b/packages/runtime-core/src/hydration.ts @@ -940,10 +940,7 @@ function resolveCssVars( for (const key in cssVars) { const value = cssVars[key] if (isString(value) || typeof value === 'number') { - expectedMap.set( - `--${getEscapedCssVarName(key, false)}`, - String(cssVars[key]), - ) + expectedMap.set(`--${getEscapedCssVarName(key, false)}`, String(value)) } } } From a29ba03af7f064b733a93e2e35ecb1861fc89281 Mon Sep 17 00:00:00 2001 From: yangchangtao Date: Wed, 20 Nov 2024 12:10:39 +0800 Subject: [PATCH 4/8] chore: update --- packages/runtime-core/__tests__/hydration.spec.ts | 8 +++++--- packages/runtime-core/src/hydration.ts | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/packages/runtime-core/__tests__/hydration.spec.ts b/packages/runtime-core/__tests__/hydration.spec.ts index b98a8af91e5..b2396e92ba3 100644 --- a/packages/runtime-core/__tests__/hydration.spec.ts +++ b/packages/runtime-core/__tests__/hydration.spec.ts @@ -2205,14 +2205,16 @@ describe('SSR hydration', () => { expect(`Hydration style mismatch`).not.toHaveBeenWarned() }) - test('should not warn on css v-bind non-string and number value', () => { + test('should not warn on css v-bind non-string & non-number & empty string value', () => { const container = document.createElement('div') container.innerHTML = `
` const app = createSSRApp({ setup() { - const backGroundColor = ref(null) + const value1 = ref(null) + const value2 = ref('') useCssVars(() => ({ - 'foo.bar': backGroundColor.value, + foo: value1.value, + bar: value2.value, })) return () => h(Child) }, diff --git a/packages/runtime-core/src/hydration.ts b/packages/runtime-core/src/hydration.ts index 7c11c01faea..96135eb3fdc 100644 --- a/packages/runtime-core/src/hydration.ts +++ b/packages/runtime-core/src/hydration.ts @@ -939,7 +939,7 @@ function resolveCssVars( const cssVars = instance.getCssVars() for (const key in cssVars) { const value = cssVars[key] - if (isString(value) || typeof value === 'number') { + if ((isString(value) && value.trim()) || typeof value === 'number') { expectedMap.set(`--${getEscapedCssVarName(key, false)}`, String(value)) } } From 7d5a67a35ca4b22f3a55e4e3bf561407d5dc46f3 Mon Sep 17 00:00:00 2001 From: yangchangtao Date: Wed, 20 Nov 2024 14:24:16 +0800 Subject: [PATCH 5/8] chore: update --- packages/runtime-core/__tests__/hydration.spec.ts | 2 +- packages/runtime-core/src/hydration.ts | 9 ++++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/packages/runtime-core/__tests__/hydration.spec.ts b/packages/runtime-core/__tests__/hydration.spec.ts index b2396e92ba3..e7596a01993 100644 --- a/packages/runtime-core/__tests__/hydration.spec.ts +++ b/packages/runtime-core/__tests__/hydration.spec.ts @@ -2207,7 +2207,7 @@ describe('SSR hydration', () => { test('should not warn on css v-bind non-string & non-number & empty string value', () => { const container = document.createElement('div') - container.innerHTML = `
` + container.innerHTML = `
` const app = createSSRApp({ setup() { const value1 = ref(null) diff --git a/packages/runtime-core/src/hydration.ts b/packages/runtime-core/src/hydration.ts index 96135eb3fdc..8b7266427bc 100644 --- a/packages/runtime-core/src/hydration.ts +++ b/packages/runtime-core/src/hydration.ts @@ -904,7 +904,7 @@ function toStyleMap(str: string): Map { let [key, value] = item.split(':') key = key.trim() value = value && value.trim() - if (key && value) { + if (key && isRenderableAttrValue(value)) { styleMap.set(key, value) } } @@ -939,8 +939,11 @@ function resolveCssVars( const cssVars = instance.getCssVars() for (const key in cssVars) { const value = cssVars[key] - if ((isString(value) && value.trim()) || typeof value === 'number') { - expectedMap.set(`--${getEscapedCssVarName(key, false)}`, String(value)) + if (isRenderableAttrValue(value)) { + expectedMap.set( + `--${getEscapedCssVarName(key, false)}`, + String(value).trim(), + ) } } } From 86de25311f4cc5495329a0db647029a340d2772f Mon Sep 17 00:00:00 2001 From: yangchangtao Date: Wed, 20 Nov 2024 16:55:25 +0800 Subject: [PATCH 6/8] chore: update setVarsOnNode --- .../__tests__/helpers/useCssVars.spec.ts | 27 +++++++++++++++++++ .../runtime-dom/src/helpers/useCssVars.ts | 10 ++++--- 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/packages/runtime-dom/__tests__/helpers/useCssVars.spec.ts b/packages/runtime-dom/__tests__/helpers/useCssVars.spec.ts index 1fb4cc65fd0..db614173304 100644 --- a/packages/runtime-dom/__tests__/helpers/useCssVars.spec.ts +++ b/packages/runtime-dom/__tests__/helpers/useCssVars.spec.ts @@ -465,4 +465,31 @@ describe('useCssVars', () => { render(h(App), root) expect(colorInOnMount).toBe(`red`) }) + + test('filter non-string、non-boolean、non-number value', () => { + const state = reactive({ + color: 'red', + size: {}, + width: false, + height: 10, + }) + const root = document.createElement('div') + let style!: CSSStyleDeclaration + + const App = { + setup() { + useCssVars(() => state) + onMounted(() => { + style = (root.children[0] as HTMLElement).style + }) + return () => h('div') + }, + } + + render(h(App), root) + expect(style.getPropertyValue(`--color`)).toBe(`red`) + expect(style.getPropertyValue(`--size`)).toBe(``) + expect(style.getPropertyValue(`--width`)).toBe(`false`) + expect(style.getPropertyValue(`--height`)).toBe(`10`) + }) }) diff --git a/packages/runtime-dom/src/helpers/useCssVars.ts b/packages/runtime-dom/src/helpers/useCssVars.ts index e2bc6de9278..883935bb061 100644 --- a/packages/runtime-dom/src/helpers/useCssVars.ts +++ b/packages/runtime-dom/src/helpers/useCssVars.ts @@ -10,7 +10,7 @@ import { warn, watch, } from '@vue/runtime-core' -import { NOOP, ShapeFlags } from '@vue/shared' +import { NOOP, ShapeFlags, isRenderableAttrValue } from '@vue/shared' export const CSS_VAR_TEXT: unique symbol = Symbol(__DEV__ ? 'CSS_VAR_TEXT' : '') /** @@ -99,8 +99,12 @@ function setVarsOnNode(el: Node, vars: Record) { const style = (el as HTMLElement).style let cssText = '' for (const key in vars) { - style.setProperty(`--${key}`, vars[key]) - cssText += `--${key}: ${vars[key]};` + const value = vars[key] + if (isRenderableAttrValue(value)) { + const trimVal = String(value).trim() + style.setProperty(`--${key}`, trimVal) + cssText += `--${key}: ${trimVal};` + } } ;(style as any)[CSS_VAR_TEXT] = cssText } From e7ce2974d70fc47dae2bdd73ffd3239b8704deea Mon Sep 17 00:00:00 2001 From: daiwei Date: Fri, 22 Nov 2024 14:01:02 +0800 Subject: [PATCH 7/8] chore: avoid affecting the client's existing rendering behavior Currently client-side rendering supports null and undefined, which prevents styles from being inherited from the parent node. --- packages/runtime-core/src/hydration.ts | 2 +- .../__tests__/helpers/useCssVars.spec.ts | 27 ------------------- .../runtime-dom/src/helpers/useCssVars.ts | 10 +++---- 3 files changed, 4 insertions(+), 35 deletions(-) diff --git a/packages/runtime-core/src/hydration.ts b/packages/runtime-core/src/hydration.ts index 8b7266427bc..bb814891504 100644 --- a/packages/runtime-core/src/hydration.ts +++ b/packages/runtime-core/src/hydration.ts @@ -904,7 +904,7 @@ function toStyleMap(str: string): Map { let [key, value] = item.split(':') key = key.trim() value = value && value.trim() - if (key && isRenderableAttrValue(value)) { + if (key) { styleMap.set(key, value) } } diff --git a/packages/runtime-dom/__tests__/helpers/useCssVars.spec.ts b/packages/runtime-dom/__tests__/helpers/useCssVars.spec.ts index db614173304..1fb4cc65fd0 100644 --- a/packages/runtime-dom/__tests__/helpers/useCssVars.spec.ts +++ b/packages/runtime-dom/__tests__/helpers/useCssVars.spec.ts @@ -465,31 +465,4 @@ describe('useCssVars', () => { render(h(App), root) expect(colorInOnMount).toBe(`red`) }) - - test('filter non-string、non-boolean、non-number value', () => { - const state = reactive({ - color: 'red', - size: {}, - width: false, - height: 10, - }) - const root = document.createElement('div') - let style!: CSSStyleDeclaration - - const App = { - setup() { - useCssVars(() => state) - onMounted(() => { - style = (root.children[0] as HTMLElement).style - }) - return () => h('div') - }, - } - - render(h(App), root) - expect(style.getPropertyValue(`--color`)).toBe(`red`) - expect(style.getPropertyValue(`--size`)).toBe(``) - expect(style.getPropertyValue(`--width`)).toBe(`false`) - expect(style.getPropertyValue(`--height`)).toBe(`10`) - }) }) diff --git a/packages/runtime-dom/src/helpers/useCssVars.ts b/packages/runtime-dom/src/helpers/useCssVars.ts index 883935bb061..e2bc6de9278 100644 --- a/packages/runtime-dom/src/helpers/useCssVars.ts +++ b/packages/runtime-dom/src/helpers/useCssVars.ts @@ -10,7 +10,7 @@ import { warn, watch, } from '@vue/runtime-core' -import { NOOP, ShapeFlags, isRenderableAttrValue } from '@vue/shared' +import { NOOP, ShapeFlags } from '@vue/shared' export const CSS_VAR_TEXT: unique symbol = Symbol(__DEV__ ? 'CSS_VAR_TEXT' : '') /** @@ -99,12 +99,8 @@ function setVarsOnNode(el: Node, vars: Record) { const style = (el as HTMLElement).style let cssText = '' for (const key in vars) { - const value = vars[key] - if (isRenderableAttrValue(value)) { - const trimVal = String(value).trim() - style.setProperty(`--${key}`, trimVal) - cssText += `--${key}: ${trimVal};` - } + style.setProperty(`--${key}`, vars[key]) + cssText += `--${key}: ${vars[key]};` } ;(style as any)[CSS_VAR_TEXT] = cssText } From 8ce63aa707fdb359357e8181b16c9080b62ed47f Mon Sep 17 00:00:00 2001 From: daiwei Date: Fri, 22 Nov 2024 14:29:38 +0800 Subject: [PATCH 8/8] test: add more case --- packages/runtime-core/__tests__/hydration.spec.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/runtime-core/__tests__/hydration.spec.ts b/packages/runtime-core/__tests__/hydration.spec.ts index e7596a01993..763356c4395 100644 --- a/packages/runtime-core/__tests__/hydration.spec.ts +++ b/packages/runtime-core/__tests__/hydration.spec.ts @@ -2205,16 +2205,18 @@ describe('SSR hydration', () => { expect(`Hydration style mismatch`).not.toHaveBeenWarned() }) - test('should not warn on css v-bind non-string & non-number & empty string value', () => { + test('style var with falsy values', () => { const container = document.createElement('div') container.innerHTML = `
` const app = createSSRApp({ setup() { const value1 = ref(null) const value2 = ref('') + const value3 = ref(undefined) useCssVars(() => ({ foo: value1.value, bar: value2.value, + baz: value3.value, })) return () => h(Child) },