diff --git a/src/reactivity/unwrap.ts b/src/reactivity/unwrap.ts index 611e178c..e5e1466c 100644 --- a/src/reactivity/unwrap.ts +++ b/src/reactivity/unwrap.ts @@ -27,6 +27,11 @@ export function unwrapRefProxy(value: any, map = new WeakMap()) { (s) => (obj[s] = (value as any)[s]) ) + // copy __ob__ + if (value.__ob__) { + Object.defineProperty(obj, '__ob__', value.__ob__) + } + for (const k of Object.keys(value)) { const r = value[k] // don't process on falsy or raw diff --git a/test/setup.spec.js b/test/setup.spec.js index 92a770ea..9dc0ba98 100644 --- a/test/setup.spec.js +++ b/test/setup.spec.js @@ -696,6 +696,33 @@ describe('setup', () => { }, }) }) + + // #392 + it('should copy __ob__ and make toRaw work when passing via props', () => { + const Foo = { + template: '

{{obj.bar}}

', + props: { + obj: { + type: Object, + required: true, + }, + }, + setup(props) { + expect(toRaw(props.obj)).toEqual({ bar: 1 }) + return {} + }, + } + + const vm = new Vue({ + template: '', + components: { Foo }, + setup() { + return { obj: { bar: ref(1) } } + }, + }).$mount() + + expect(vm.$el.textContent).toBe('1') + }) }) it('should not unwrap built-in objects on the template', () => {