]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(runtime-dom): check attribute value when setting option value (#8246)
authorlinghaoSu <slh001@live.cn>
Mon, 8 May 2023 07:26:14 +0000 (15:26 +0800)
committerGitHub <noreply@github.com>
Mon, 8 May 2023 07:26:14 +0000 (15:26 +0800)
fix #8227

packages/runtime-dom/__tests__/patchProps.spec.ts
packages/runtime-dom/src/modules/props.ts

index c49de1a155da236faf9c170abdc76d26b7141bcf..88cf916252bb495fa348de7ea567224824298ca1 100644 (file)
@@ -24,6 +24,14 @@ describe('runtime-dom: props patching', () => {
     patchProp(el, 'value', null, obj)
     expect(el.value).toBe(obj.toString())
     expect((el as any)._value).toBe(obj)
+
+    const option = document.createElement('option')
+    patchProp(option, 'textContent', null, 'foo')
+    expect(option.value).toBe('foo')
+    expect(option.getAttribute('value')).toBe(null)
+    patchProp(option, 'value', null, 'foo')
+    expect(option.value).toBe('foo')
+    expect(option.getAttribute('value')).toBe('foo')
   })
 
   test('value for custom elements', () => {
index 1c1ad0c16f7a072e97ac94618a5d27bda1102d07..cdf9d84cf5d72f024b82dba85431cfe2bd974d03 100644 (file)
@@ -26,23 +26,22 @@ export function patchDOMProp(
     return
   }
 
+  const tag = el.tagName
+
   if (
     key === 'value' &&
-    el.tagName !== 'PROGRESS' &&
+    tag !== 'PROGRESS' &&
     // custom elements may use _value internally
-    !el.tagName.includes('-')
+    !tag.includes('-')
   ) {
     // store value as _value as well since
     // non-string values will be stringified.
     el._value = value
+    // #4956: <option> value will fallback to its text content so we need to
+    // compare against its attribute value instead.
+    const oldValue = tag === 'OPTION' ? el.getAttribute('value') : el.value
     const newValue = value == null ? '' : value
-    if (
-      el.value !== newValue ||
-      // #4956: always set for OPTION elements because its value falls back to
-      // textContent if no value attribute is present. And setting .value for
-      // OPTION has no side effect
-      el.tagName === 'OPTION'
-    ) {
+    if (oldValue !== newValue) {
       el.value = newValue
     }
     if (value == null) {
@@ -98,7 +97,7 @@ export function patchDOMProp(
     // do not warn if value is auto-coerced from nullish values
     if (__DEV__ && !needRemove) {
       warn(
-        `Failed setting prop "${key}" on <${el.tagName.toLowerCase()}>: ` +
+        `Failed setting prop "${key}" on <${tag.toLowerCase()}>: ` +
           `value ${value} is invalid.`,
         e
       )