diff --git a/packages/runtime-dom/src/patchProp.ts b/packages/runtime-dom/src/patchProp.ts index bd30e8aa..b664b095 100644 --- a/packages/runtime-dom/src/patchProp.ts +++ b/packages/runtime-dom/src/patchProp.ts @@ -5,6 +5,7 @@ import { patchDOMProp } from './modules/props' import { patchEvent } from './modules/events' import { isOn, isString, isFunction } from '@vue/shared' import { RendererOptions } from '@vue/runtime-core' +import { chdir } from 'process' const nativeOnRE = /^on[a-z]/ @@ -38,26 +39,7 @@ export const patchProp: DOMRendererOptions['patchProp'] = ( if (!key.startsWith('onUpdate:')) { patchEvent(el, key, prevValue, nextValue, parentComponent) } - } else if ( - // spellcheck and draggable are numerated attrs, however their - // corresponding DOM properties are actually booleans - this leads to - // setting it with a string "false" value leading it to be coerced to - // `true`, so we need to always treat them as attributes. - // Note that `contentEditable` doesn't have this problem: its DOM - // property is also enumerated string values. - key !== 'spellcheck' && - key !== 'draggable' && - (isSVG - ? // most keys must be set as attribute on svg elements to work - // ...except innerHTML - key === 'innerHTML' || - // or native onclick with function values - (key in el && nativeOnRE.test(key) && isFunction(nextValue)) - : // for normal html elements, set as a property if it exists - key in el && - // except native onclick with string values - !(nativeOnRE.test(key) && isString(nextValue))) - ) { + } else if (shouldSetAsProp(el, key, nextValue, isSVG)) { patchDOMProp( el, key, @@ -82,3 +64,45 @@ export const patchProp: DOMRendererOptions['patchProp'] = ( break } } + +function shouldSetAsProp( + el: Element, + key: string, + value: unknown, + isSVG: boolean +) { + if (isSVG) { + // most keys must be set as attribute on svg elements to work + // ...except innerHTML + if (key === 'innerHTML') { + return true + } + // or native onclick with function values + if (key in el && nativeOnRE.test(key) && isFunction(value)) { + return true + } + return false + } + + // spellcheck and draggable are numerated attrs, however their + // corresponding DOM properties are actually booleans - this leads to + // setting it with a string "false" value leading it to be coerced to + // `true`, so we need to always treat them as attributes. + // Note that `contentEditable` doesn't have this problem: its DOM + // property is also enumerated string values. + if (key === 'spellcheck' || key === 'draggable') { + return false + } + + // #1526 must be set as attribute + if (key === 'list' && el.tagName === 'INPUT') { + return false + } + + // native onclick with string value, must be set as attribute + if (nativeOnRE.test(key) && isString(value)) { + return false + } + + return key in el +}