diff --git a/packages/runtime-dom/__tests__/patchProps.spec.ts b/packages/runtime-dom/__tests__/patchProps.spec.ts index bf6362e7a0c..19554b02810 100644 --- a/packages/runtime-dom/__tests__/patchProps.spec.ts +++ b/packages/runtime-dom/__tests__/patchProps.spec.ts @@ -291,6 +291,15 @@ describe('runtime-dom: props patching', () => { expect(el.value).toBe('baz') }) + // #8780 + test('embedded tag with width and height', () => { + // Width and height of some embedded element such as img、video、source、canvas + // must be set as attribute + const el = document.createElement('img') + patchProp(el, 'width', null, '24px') + expect(el.getAttribute('width')).toBe('24px') + }) + test('translate attribute', () => { const el = document.createElement('div') patchProp(el, 'translate', null, 'no') diff --git a/packages/runtime-dom/src/patchProp.ts b/packages/runtime-dom/src/patchProp.ts index 38ad5b9f8b8..15f4f73edc4 100644 --- a/packages/runtime-dom/src/patchProp.ts +++ b/packages/runtime-dom/src/patchProp.ts @@ -8,6 +8,8 @@ import { RendererOptions } from '@vue/runtime-core' const nativeOnRE = /^on[a-z]/ +const embeddedTags = ['IMG', 'VIDEO', 'CANVAS', 'SOURCE'] + type DOMRendererOptions = RendererOptions export const patchProp: DOMRendererOptions['patchProp'] = ( @@ -105,6 +107,14 @@ function shouldSetAsProp( return false } + // #8780 the width or heigth of embedded tags must be set as attribute + if ( + (key === 'width' || key === 'height') && + embeddedTags.includes(el.tagName) + ) { + return false + } + // native onclick with string value, must be set as attribute if (nativeOnRE.test(key) && isString(value)) { return false