Просмотр исходного кода

fix(runtime-dom): avoid unset option's value (#10416)

close #10412
re-fix #10396
Doctor Wu 2 лет назад
Родитель
Сommit
b3f8b5a4e7

+ 12 - 0
packages/runtime-dom/__tests__/patchProps.spec.ts

@@ -291,6 +291,18 @@ describe('runtime-dom: props patching', () => {
     expect(el.value).toBe('baz')
   })
 
+  test('init empty value for option', () => {
+    const root = document.createElement('div')
+    render(
+      h('select', { value: 'foo' }, [h('option', { value: '' }, 'foo')]),
+      root,
+    )
+    const select = root.children[0] as HTMLSelectElement
+    const option = select.children[0] as HTMLOptionElement
+    expect(select.value).toBe('')
+    expect(option.value).toBe('')
+  })
+
   // #8780
   test('embedded tag with width and height', () => {
     // Width and height of some embedded element such as img、video、source、canvas

+ 4 - 4
packages/runtime-dom/src/modules/props.ts

@@ -34,20 +34,20 @@ export function patchDOMProp(
     // custom elements may use _value internally
     !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 (oldValue !== newValue) {
+    if (oldValue !== newValue || !('_value' in el)) {
       el.value = newValue
     }
     if (value == null) {
       el.removeAttribute(key)
     }
+    // store value as _value as well since
+    // non-string values will be stringified.
+    el._value = value
     return
   }