diff --git a/packages/runtime-dom/src/patchProp.ts b/packages/runtime-dom/src/patchProp.ts index 15f4f73edc4..28753a90380 100644 --- a/packages/runtime-dom/src/patchProp.ts +++ b/packages/runtime-dom/src/patchProp.ts @@ -6,7 +6,12 @@ import { patchEvent } from './modules/events' import { isOn, isString, isFunction, isModelListener } from '@vue/shared' import { RendererOptions } from '@vue/runtime-core' -const nativeOnRE = /^on[a-z]/ +const isNativeOn = (key: string) => + key.charCodeAt(0) === 111 /* o */ && + key.charCodeAt(1) === 110 /* n */ && + // lowercase letter + key.charCodeAt(2) > 96 && + key.charCodeAt(2) < 123 const embeddedTags = ['IMG', 'VIDEO', 'CANVAS', 'SOURCE'] @@ -75,7 +80,7 @@ function shouldSetAsProp( return true } // or native onclick with function values - if (key in el && nativeOnRE.test(key) && isFunction(value)) { + if (key in el && isNativeOn(key) && isFunction(value)) { return true } return false @@ -116,7 +121,7 @@ function shouldSetAsProp( } // native onclick with string value, must be set as attribute - if (nativeOnRE.test(key) && isString(value)) { + if (isNativeOn(key) && isString(value)) { return false } diff --git a/packages/shared/src/general.ts b/packages/shared/src/general.ts index 50e7eb42728..dcde4c8c6cc 100644 --- a/packages/shared/src/general.ts +++ b/packages/shared/src/general.ts @@ -12,8 +12,11 @@ export const NOOP = () => {} */ export const NO = () => false -const onRE = /^on[^a-z]/ -export const isOn = (key: string) => onRE.test(key) +export const isOn = (key: string) => + key.charCodeAt(0) === 111 /* o */ && + key.charCodeAt(1) === 110 /* n */ && + // uppercase letter + (key.charCodeAt(2) > 122 || key.charCodeAt(2) < 97) export const isModelListener = (key: string) => key.startsWith('onUpdate:')