From: Evan You Date: Fri, 27 Sep 2024 01:25:00 +0000 (+0800) Subject: fix(custom-element): properly set kebab-case props on Vue custom elements X-Git-Tag: v3.5.10~5 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=ea3efa09e008918c1d9ba7226833a8b1a7a57244;p=thirdparty%2Fvuejs%2Fcore.git fix(custom-element): properly set kebab-case props on Vue custom elements close #12030 close #12032 --- diff --git a/packages/runtime-dom/__tests__/customElement.spec.ts b/packages/runtime-dom/__tests__/customElement.spec.ts index 51113edef6..ef5051f42f 100644 --- a/packages/runtime-dom/__tests__/customElement.spec.ts +++ b/packages/runtime-dom/__tests__/customElement.spec.ts @@ -223,6 +223,21 @@ describe('defineCustomElement', () => { expect(e.getAttribute('baz-qux')).toBe('four') }) + test('props via hyphen property', async () => { + const Comp = defineCustomElement({ + props: { + fooBar: Boolean, + }, + render() { + return 'Comp' + }, + }) + customElements.define('my-el-comp', Comp) + render(h('my-el-comp', { 'foo-bar': true }), container) + const el = container.children[0] + expect((el as any).outerHTML).toBe('') + }) + test('attribute -> prop type casting', async () => { const E = defineCustomElement({ props: { diff --git a/packages/runtime-dom/src/patchProp.ts b/packages/runtime-dom/src/patchProp.ts index 98b69967c7..5814e77c4f 100644 --- a/packages/runtime-dom/src/patchProp.ts +++ b/packages/runtime-dom/src/patchProp.ts @@ -3,7 +3,13 @@ import { patchStyle } from './modules/style' import { patchAttr } from './modules/attrs' import { patchDOMProp } from './modules/props' import { patchEvent } from './modules/events' -import { isFunction, isModelListener, isOn, isString } from '@vue/shared' +import { + camelize, + isFunction, + isModelListener, + isOn, + isString, +} from '@vue/shared' import type { RendererOptions } from '@vue/runtime-core' import type { VueElement } from './apiCustomElement' @@ -51,6 +57,12 @@ export const patchProp: DOMRendererOptions['patchProp'] = ( ) { patchAttr(el, key, nextValue, isSVG, parentComponent, key !== 'value') } + } else if ( + // #11081 force set props for possible async custom element + (el as VueElement)._isVueCE && + (/[A-Z]/.test(key) || !isString(nextValue)) + ) { + patchDOMProp(el, camelize(key), nextValue, parentComponent) } else { // special case for with // :true-value & :false-value @@ -128,14 +140,5 @@ function shouldSetAsProp( return false } - if (key in el) { - return true - } - - // #11081 force set props for possible async custom element - if ((el as VueElement)._isVueCE && (/[A-Z]/.test(key) || !isString(value))) { - return true - } - - return false + return key in el }