From 80cbb28d624fc44701fbf3d18a93b340fa453991 Mon Sep 17 00:00:00 2001 From: yangchangtao Date: Wed, 31 Jan 2024 21:11:53 +0800 Subject: [PATCH 1/7] fix(hydration): fix --- packages/runtime-core/src/component.ts | 5 ++++- packages/runtime-core/src/hydration.ts | 15 ++++++++++++++- packages/runtime-dom/src/helpers/useCssVars.ts | 8 +++++++- 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/packages/runtime-core/src/component.ts b/packages/runtime-core/src/component.ts index 1508627e579..536b85555f2 100644 --- a/packages/runtime-core/src/component.ts +++ b/packages/runtime-core/src/component.ts @@ -518,7 +518,10 @@ export interface ComponentInternalInstance { * For updating css vars on contained teleports * @internal */ - ut?: (vars?: Record) => void + ut?: ( + vars?: Record, + ssr?: boolean, + ) => void | Record } const emptyAppContext = createAppContext() diff --git a/packages/runtime-core/src/hydration.ts b/packages/runtime-core/src/hydration.ts index b22afdb7aa5..5b77bf28d9f 100644 --- a/packages/runtime-core/src/hydration.ts +++ b/packages/runtime-core/src/hydration.ts @@ -448,8 +448,15 @@ export function createHydrationFunctions( patchFlag & (PatchFlags.FULL_PROPS | PatchFlags.NEED_HYDRATION) ) { for (const key in props) { + const cssVars = parentComponent?.ut?.(undefined, true) as Record< + string, + string + > // check hydration mismatch - if (__DEV__ && propHasMismatch(el, key, props[key], vnode)) { + if ( + __DEV__ && + propHasMismatch(el, key, props[key], vnode, cssVars) + ) { hasMismatch = true } if ( @@ -718,6 +725,7 @@ function propHasMismatch( key: string, clientValue: any, vnode: VNode, + cssVars?: Record, ): boolean { let mismatchType: string | undefined let mismatchKey: string | undefined @@ -748,6 +756,11 @@ function propHasMismatch( } } } + if (cssVars) { + for (const key in cssVars) { + expectedMap.set(key, cssVars[key]) + } + } if (!isMapEqual(actualMap, expectedMap)) { mismatchType = mismatchKey = 'style' } diff --git a/packages/runtime-dom/src/helpers/useCssVars.ts b/packages/runtime-dom/src/helpers/useCssVars.ts index 72714e6f623..e6f0e5b2de4 100644 --- a/packages/runtime-dom/src/helpers/useCssVars.ts +++ b/packages/runtime-dom/src/helpers/useCssVars.ts @@ -26,7 +26,13 @@ export function useCssVars(getter: (ctx: any) => Record) { return } - const updateTeleports = (instance.ut = (vars = getter(instance.proxy)) => { + const updateTeleports = (instance.ut = ( + vars = getter(instance.proxy), + ssr = false, + ) => { + if (ssr) { + return vars + } Array.from( document.querySelectorAll(`[data-v-owner="${instance.uid}"]`), ).forEach(node => setVarsOnNode(node, vars)) From 01af548ebcbbf6ee89b329ca3da27a4bcbf4310f Mon Sep 17 00:00:00 2001 From: RicardoErii <‘1974364190@qq.com’> Date: Thu, 1 Feb 2024 00:41:45 +0800 Subject: [PATCH 2/7] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/runtime-core/src/component.ts | 2 +- packages/runtime-core/src/hydration.ts | 8 ++++---- packages/runtime-dom/src/helpers/useCssVars.ts | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/runtime-core/src/component.ts b/packages/runtime-core/src/component.ts index 536b85555f2..0adcc30f217 100644 --- a/packages/runtime-core/src/component.ts +++ b/packages/runtime-core/src/component.ts @@ -520,7 +520,7 @@ export interface ComponentInternalInstance { */ ut?: ( vars?: Record, - ssr?: boolean, + hydration?: boolean, ) => void | Record } diff --git a/packages/runtime-core/src/hydration.ts b/packages/runtime-core/src/hydration.ts index 5b77bf28d9f..5739f40beaf 100644 --- a/packages/runtime-core/src/hydration.ts +++ b/packages/runtime-core/src/hydration.ts @@ -447,11 +447,11 @@ export function createHydrationFunctions( !optimized || patchFlag & (PatchFlags.FULL_PROPS | PatchFlags.NEED_HYDRATION) ) { + const cssVars = parentComponent?.ut?.(undefined, true) as Record< + string, + string + > for (const key in props) { - const cssVars = parentComponent?.ut?.(undefined, true) as Record< - string, - string - > // check hydration mismatch if ( __DEV__ && diff --git a/packages/runtime-dom/src/helpers/useCssVars.ts b/packages/runtime-dom/src/helpers/useCssVars.ts index e6f0e5b2de4..1944bfe9a94 100644 --- a/packages/runtime-dom/src/helpers/useCssVars.ts +++ b/packages/runtime-dom/src/helpers/useCssVars.ts @@ -28,9 +28,9 @@ export function useCssVars(getter: (ctx: any) => Record) { const updateTeleports = (instance.ut = ( vars = getter(instance.proxy), - ssr = false, + hydration = false, ) => { - if (ssr) { + if (hydration) { return vars } Array.from( From e559a341e1aabedb2f3628273dadc42d0a79b4fb Mon Sep 17 00:00:00 2001 From: yangchangtao Date: Thu, 1 Feb 2024 11:00:41 +0800 Subject: [PATCH 3/7] refactor: refactor --- packages/runtime-core/src/component.ts | 11 +++++++---- packages/runtime-core/src/hydration.ts | 5 +---- .../runtime-dom/src/helpers/useCssVars.ts | 19 ++++++++++++------- 3 files changed, 20 insertions(+), 15 deletions(-) diff --git a/packages/runtime-core/src/component.ts b/packages/runtime-core/src/component.ts index 0adcc30f217..a0105d897b5 100644 --- a/packages/runtime-core/src/component.ts +++ b/packages/runtime-core/src/component.ts @@ -518,10 +518,13 @@ export interface ComponentInternalInstance { * For updating css vars on contained teleports * @internal */ - ut?: ( - vars?: Record, - hydration?: boolean, - ) => void | Record + ut?: (vars?: Record) => void + + /** + * For getCssVars on hydration + * @internal + */ + getCssVars?: () => Record } const emptyAppContext = createAppContext() diff --git a/packages/runtime-core/src/hydration.ts b/packages/runtime-core/src/hydration.ts index 5739f40beaf..9600ca3d8e2 100644 --- a/packages/runtime-core/src/hydration.ts +++ b/packages/runtime-core/src/hydration.ts @@ -447,10 +447,7 @@ export function createHydrationFunctions( !optimized || patchFlag & (PatchFlags.FULL_PROPS | PatchFlags.NEED_HYDRATION) ) { - const cssVars = parentComponent?.ut?.(undefined, true) as Record< - string, - string - > + const cssVars = parentComponent?.getCssVars?.() for (const key in props) { // check hydration mismatch if ( diff --git a/packages/runtime-dom/src/helpers/useCssVars.ts b/packages/runtime-dom/src/helpers/useCssVars.ts index 1944bfe9a94..cbd3712e204 100644 --- a/packages/runtime-dom/src/helpers/useCssVars.ts +++ b/packages/runtime-dom/src/helpers/useCssVars.ts @@ -26,18 +26,16 @@ export function useCssVars(getter: (ctx: any) => Record) { return } - const updateTeleports = (instance.ut = ( - vars = getter(instance.proxy), - hydration = false, - ) => { - if (hydration) { - return vars - } + const updateTeleports = (instance.ut = (vars = getter(instance.proxy)) => { Array.from( document.querySelectorAll(`[data-v-owner="${instance.uid}"]`), ).forEach(node => setVarsOnNode(node, vars)) }) + if (__DEV__ && __SSR__) { + instance.getCssVars = () => fommaterVars(getter(instance.proxy)) + } + const setVars = () => { const vars = getter(instance.proxy) setVarsOnVNode(instance.subTree, vars) @@ -94,3 +92,10 @@ function setVarsOnNode(el: Node, vars: Record) { ;(style as any)[CSS_VAR_TEXT] = cssText } } +function fommaterVars(vars: Record) { + const cssVars: Record = {} + for (const key in vars) { + cssVars[`--${key}`] = vars[key] + } + return cssVars +} From d1d96519c7dbca3660cb11ce6d1de0ccd4ad8e4d Mon Sep 17 00:00:00 2001 From: yangchangtao Date: Thu, 1 Feb 2024 11:56:19 +0800 Subject: [PATCH 4/7] perf: resolve common --- packages/runtime-core/src/component.ts | 2 +- packages/runtime-core/src/hydration.ts | 3 ++- packages/runtime-dom/src/helpers/useCssVars.ts | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/runtime-core/src/component.ts b/packages/runtime-core/src/component.ts index a0105d897b5..a88387ced5e 100644 --- a/packages/runtime-core/src/component.ts +++ b/packages/runtime-core/src/component.ts @@ -521,7 +521,7 @@ export interface ComponentInternalInstance { ut?: (vars?: Record) => void /** - * For getCssVars on hydration + * dev only. For getCssVars on hydration * @internal */ getCssVars?: () => Record diff --git a/packages/runtime-core/src/hydration.ts b/packages/runtime-core/src/hydration.ts index 9600ca3d8e2..a2dca680417 100644 --- a/packages/runtime-core/src/hydration.ts +++ b/packages/runtime-core/src/hydration.ts @@ -447,7 +447,8 @@ export function createHydrationFunctions( !optimized || patchFlag & (PatchFlags.FULL_PROPS | PatchFlags.NEED_HYDRATION) ) { - const cssVars = parentComponent?.getCssVars?.() + let cssVars + if (__DEV__) cssVars = parentComponent?.getCssVars?.() for (const key in props) { // check hydration mismatch if ( diff --git a/packages/runtime-dom/src/helpers/useCssVars.ts b/packages/runtime-dom/src/helpers/useCssVars.ts index cbd3712e204..f0a1ceedd1f 100644 --- a/packages/runtime-dom/src/helpers/useCssVars.ts +++ b/packages/runtime-dom/src/helpers/useCssVars.ts @@ -32,7 +32,7 @@ export function useCssVars(getter: (ctx: any) => Record) { ).forEach(node => setVarsOnNode(node, vars)) }) - if (__DEV__ && __SSR__) { + if (__DEV__) { instance.getCssVars = () => fommaterVars(getter(instance.proxy)) } From a5b64a4d0dc9902d4885666d8316453366437497 Mon Sep 17 00:00:00 2001 From: yangchangtao Date: Fri, 2 Feb 2024 19:31:40 +0800 Subject: [PATCH 5/7] fix: #10259 --- packages/runtime-dom/src/helpers/useCssVars.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/runtime-dom/src/helpers/useCssVars.ts b/packages/runtime-dom/src/helpers/useCssVars.ts index f0a1ceedd1f..02a05a2cb61 100644 --- a/packages/runtime-dom/src/helpers/useCssVars.ts +++ b/packages/runtime-dom/src/helpers/useCssVars.ts @@ -95,7 +95,7 @@ function setVarsOnNode(el: Node, vars: Record) { function fommaterVars(vars: Record) { const cssVars: Record = {} for (const key in vars) { - cssVars[`--${key}`] = vars[key] + cssVars[`--${key}`] = String(vars[key]) } return cssVars } From 4fed80b59c68b6cd198e6afbdf27f41aab49ae56 Mon Sep 17 00:00:00 2001 From: Evan You Date: Tue, 6 Feb 2024 17:29:43 +0800 Subject: [PATCH 6/7] refactor: simplify implementation --- packages/runtime-core/src/component.ts | 2 +- packages/runtime-core/src/hydration.ts | 15 +++++++-------- packages/runtime-dom/src/helpers/useCssVars.ts | 9 +-------- 3 files changed, 9 insertions(+), 17 deletions(-) diff --git a/packages/runtime-core/src/component.ts b/packages/runtime-core/src/component.ts index a88387ced5e..ed1f8efee52 100644 --- a/packages/runtime-core/src/component.ts +++ b/packages/runtime-core/src/component.ts @@ -521,7 +521,7 @@ export interface ComponentInternalInstance { ut?: (vars?: Record) => void /** - * dev only. For getCssVars on hydration + * dev only. For style v-bind hydration mismatch checks * @internal */ getCssVars?: () => Record diff --git a/packages/runtime-core/src/hydration.ts b/packages/runtime-core/src/hydration.ts index a2dca680417..1e9200ce27b 100644 --- a/packages/runtime-core/src/hydration.ts +++ b/packages/runtime-core/src/hydration.ts @@ -447,13 +447,11 @@ export function createHydrationFunctions( !optimized || patchFlag & (PatchFlags.FULL_PROPS | PatchFlags.NEED_HYDRATION) ) { - let cssVars - if (__DEV__) cssVars = parentComponent?.getCssVars?.() for (const key in props) { // check hydration mismatch if ( __DEV__ && - propHasMismatch(el, key, props[key], vnode, cssVars) + propHasMismatch(el, key, props[key], vnode, parentComponent) ) { hasMismatch = true } @@ -723,7 +721,7 @@ function propHasMismatch( key: string, clientValue: any, vnode: VNode, - cssVars?: Record, + instance: ComponentInternalInstance | null, ): boolean { let mismatchType: string | undefined let mismatchKey: string | undefined @@ -754,11 +752,12 @@ function propHasMismatch( } } } - if (cssVars) { - for (const key in cssVars) { - expectedMap.set(key, cssVars[key]) - } + + const cssVars = instance?.getCssVars?.() + for (const key in cssVars) { + expectedMap.set(`--${key}`, String(cssVars[key])) } + if (!isMapEqual(actualMap, expectedMap)) { mismatchType = mismatchKey = 'style' } diff --git a/packages/runtime-dom/src/helpers/useCssVars.ts b/packages/runtime-dom/src/helpers/useCssVars.ts index 02a05a2cb61..1666e3cb3dc 100644 --- a/packages/runtime-dom/src/helpers/useCssVars.ts +++ b/packages/runtime-dom/src/helpers/useCssVars.ts @@ -33,7 +33,7 @@ export function useCssVars(getter: (ctx: any) => Record) { }) if (__DEV__) { - instance.getCssVars = () => fommaterVars(getter(instance.proxy)) + instance.getCssVars = () => getter(instance.proxy) } const setVars = () => { @@ -92,10 +92,3 @@ function setVarsOnNode(el: Node, vars: Record) { ;(style as any)[CSS_VAR_TEXT] = cssText } } -function fommaterVars(vars: Record) { - const cssVars: Record = {} - for (const key in vars) { - cssVars[`--${key}`] = String(vars[key]) - } - return cssVars -} From d4bb921214c87214d41c55652d033595dfac9569 Mon Sep 17 00:00:00 2001 From: Evan You Date: Tue, 6 Feb 2024 17:36:06 +0800 Subject: [PATCH 7/7] chore: add test case --- .../runtime-core/__tests__/hydration.spec.ts | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/packages/runtime-core/__tests__/hydration.spec.ts b/packages/runtime-core/__tests__/hydration.spec.ts index 127c0d88c7f..3fa0d7e732e 100644 --- a/packages/runtime-core/__tests__/hydration.spec.ts +++ b/packages/runtime-core/__tests__/hydration.spec.ts @@ -19,6 +19,7 @@ import { onMounted, ref, renderSlot, + useCssVars, vModelCheckbox, vShow, withDirectives, @@ -1538,5 +1539,20 @@ describe('SSR hydration', () => { ) expect(`Hydration attribute mismatch`).not.toHaveBeenWarned() }) + + test('should not warn css v-bind', () => { + const container = document.createElement('div') + container.innerHTML = `
` + const app = createSSRApp({ + setup() { + useCssVars(() => ({ + foo: 'red', + })) + return () => h('div', { style: { color: 'var(--foo)' } }) + }, + }) + app.mount(container) + expect(`Hydration style mismatch`).not.toHaveBeenWarned() + }) }) })