diff --git a/packages/runtime-core/__tests__/apiSetupContext.spec.ts b/packages/runtime-core/__tests__/apiSetupContext.spec.ts index bc3c2065034..6f641da2a3a 100644 --- a/packages/runtime-core/__tests__/apiSetupContext.spec.ts +++ b/packages/runtime-core/__tests__/apiSetupContext.spec.ts @@ -24,14 +24,30 @@ describe('api: setup context', () => { // object exposed as-is object: reactive({ msg: 'bar' }), // primitive value exposed as-is - value: 'baz' + value: 'baz', + // nested ref at the end should auto-unwrap + nested: { ref: ref('qux') }, + // ref with nested should auto-unwrap + refNested: ref({ + nested: { + ref: ref('foo') + } + }), + // nested ref in the middle should auto-unwrap + refMiddleNested: { + nested: ref({ + msg: 'bar' + }) + } } }, render() { - return `${this.ref} ${this.object.msg} ${this.value}` + return `${this.ref} ${this.object.msg} ${this.value} ${ + this.nested.ref + } ${this.refNested.nested.ref} ${this.refMiddleNested.nested.msg}` } }) - expect(renderToString(h(Comp))).toMatch(`foo bar baz`) + expect(renderToString(h(Comp))).toMatch(`foo bar baz qux foo bar`) }) it('should support returning render function', () => { diff --git a/packages/runtime-core/src/componentProxy.ts b/packages/runtime-core/src/componentProxy.ts index 4582496e442..0a1627c1953 100644 --- a/packages/runtime-core/src/componentProxy.ts +++ b/packages/runtime-core/src/componentProxy.ts @@ -1,14 +1,26 @@ import { ComponentInternalInstance, Data, Emit } from './component' import { nextTick, queueJob } from './scheduler' import { instanceWatch } from './apiWatch' -import { EMPTY_OBJ, hasOwn, isGloballyWhitelisted, NOOP } from '@vue/shared' +import { + EMPTY_OBJ, + hasOwn, + isGloballyWhitelisted, + NOOP, + isObject +} from '@vue/shared' import { ExtractComputedReturns, ComponentOptionsBase, ComputedOptions, MethodOptions } from './apiOptions' -import { UnwrapRef, ReactiveEffect, isRef, isReactive } from '@vue/reactivity' +import { + UnwrapRef, + ReactiveEffect, + isRef, + isReactive, + reactive +} from '@vue/reactivity' import { warn } from './warning' import { Slots } from './componentSlots' import { @@ -72,7 +84,8 @@ const enum AccessTypes { OTHER } -const unwrapRef = (val: unknown) => (isRef(val) ? val.value : val) +const unwrapRef = (val: unknown) => + isRef(val) ? val.value : isObject(val) ? reactive(val) : val export const PublicInstanceProxyHandlers: ProxyHandler = { get(target: ComponentInternalInstance, key: string) {