diff --git a/packages/runtime-core/src/vnode.ts b/packages/runtime-core/src/vnode.ts index 57c0cf8b7d2..9f693e4d800 100644 --- a/packages/runtime-core/src/vnode.ts +++ b/packages/runtime-core/src/vnode.ts @@ -642,11 +642,25 @@ function _createVNode( ) } +function generateProps(props: Data & VNodeProps) { + const target: Data & VNodeProps = {} + for (const key in props) { + if (isObject(props[key])) { + target[key] = generateProps(props[key]) + } else { + target[key] = props[key] + } + } + return target +} + export function guardReactiveProps( props: (Data & VNodeProps) | null, ): (Data & VNodeProps) | null { if (!props) return null - return isProxy(props) || isInternalObject(props) ? extend({}, props) : props + return isProxy(props) || isInternalObject(props) + ? generateProps(props) + : props } export function cloneVNode( diff --git a/packages/runtime-dom/__tests__/patchProps.spec.ts b/packages/runtime-dom/__tests__/patchProps.spec.ts index 952508f8f91..de001e6be1b 100644 --- a/packages/runtime-dom/__tests__/patchProps.spec.ts +++ b/packages/runtime-dom/__tests__/patchProps.spec.ts @@ -1,5 +1,15 @@ import { patchProp } from '../src/patchProp' -import { h, nextTick, ref, render } from '../src' +import { + createElementBlock, + guardReactiveProps, + h, + nextTick, + normalizeProps, + reactive, + ref, + render, + toRefs, +} from '../src' describe('runtime-dom: props patching', () => { test('basic', () => { @@ -351,4 +361,37 @@ describe('runtime-dom: props patching', () => { expect(el.translate).toBeFalsy() expect(el.getAttribute('translate')).toBe('no') }) + + // #11691 + test('should update the color style of the element from red to yellow', async () => { + const state = reactive({ + obj: { + style: { + color: 'red', + }, + }, + }) + const App = { + setup() { + const { obj } = toRefs(state) + return () => { + //
msg
+ return createElementBlock( + 'div', + normalizeProps(guardReactiveProps(obj.value)), + 'msg', + 17, + ) + } + }, + } + const root = document.createElement('div') + render(h(App), root) + const el = root.children[0] as HTMLSelectElement + expect(el.style.color).toBe('red') + + state.obj.style.color = 'yellow' + await nextTick() + expect(el.style.color).toBe('yellow') + }) })