ソースを参照

fix(hydration): improve attr hydration mismatch check for boolean attrs

close #10057
close #10060
Evan You 2 年 前
コミット
972facee0d

+ 15 - 0
packages/runtime-core/__tests__/hydration.spec.ts

@@ -1489,5 +1489,20 @@ describe('SSR hydration', () => {
       mountWithHydration(`<div id="bar"></div>`, () => h('div', { id: 'foo' }))
       expect(`Hydration attribute mismatch`).toHaveBeenWarnedTimes(2)
     })
+
+    test('boolean attr handling', () => {
+      mountWithHydration(`<input />`, () => h('input', { readonly: false }))
+      expect(`Hydration attribute mismatch`).not.toHaveBeenWarned()
+
+      mountWithHydration(`<input readonly />`, () =>
+        h('input', { readonly: true }),
+      )
+      expect(`Hydration attribute mismatch`).not.toHaveBeenWarned()
+
+      mountWithHydration(`<input readonly="readonly" />`, () =>
+        h('input', { readonly: true }),
+      )
+      expect(`Hydration attribute mismatch`).not.toHaveBeenWarned()
+    })
   })
 })

+ 12 - 13
packages/runtime-core/src/hydration.ts

@@ -754,19 +754,18 @@ function propHasMismatch(
     (el instanceof SVGElement && isKnownSvgAttr(key)) ||
     (el instanceof HTMLElement && (isBooleanAttr(key) || isKnownHtmlAttr(key)))
   ) {
-    // #10000 some attrs such as textarea.value can't be get by `hasAttribute`
-    actual = el.hasAttribute(key)
-      ? el.getAttribute(key)
-      : key in el
-        ? el[key as keyof typeof el]
-        : ''
-    expected = isBooleanAttr(key)
-      ? includeBooleanAttr(clientValue)
-        ? ''
-        : false
-      : clientValue == null
-        ? ''
-        : String(clientValue)
+    if (isBooleanAttr(key)) {
+      actual = el.hasAttribute(key)
+      expected = includeBooleanAttr(clientValue)
+    } else {
+      // #10000 some attrs such as textarea.value can't be get by `hasAttribute`
+      actual = el.hasAttribute(key)
+        ? el.getAttribute(key)
+        : key in el
+          ? el[key as keyof typeof el]
+          : ''
+      expected = clientValue == null ? '' : String(clientValue)
+    }
     if (actual !== expected) {
       mismatchType = `attribute`
       mismatchKey = key