From 3a1837fbc73cb51e80481970e501b94d14bee4b5 Mon Sep 17 00:00:00 2001 From: webfansplz <308241863@qq.com> Date: Sat, 21 Aug 2021 16:37:12 +0800 Subject: [PATCH] fix(set): reactive in SSR w/ set (#796) Co-authored-by: webfansplz <> --- src/reactivity/reactive.ts | 2 +- src/reactivity/set.ts | 16 ++++++++++++++-- test/ssr/ssrReactive.spec.ts | 7 +++++++ 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/src/reactivity/reactive.ts b/src/reactivity/reactive.ts index d08b7c5b..f7ddc8fa 100644 --- a/src/reactivity/reactive.ts +++ b/src/reactivity/reactive.ts @@ -135,7 +135,7 @@ export function observe(obj: T): T { /** * Mock __ob__ for object recursively */ -function mockReactivityDeep(obj: any, seen = new Set()) { +export function mockReactivityDeep(obj: any, seen = new Set()) { if (seen.has(obj)) return def(obj, '__ob__', mockObserver(obj)) diff --git a/src/reactivity/set.ts b/src/reactivity/set.ts index dfbd40f4..2270c9ec 100644 --- a/src/reactivity/set.ts +++ b/src/reactivity/set.ts @@ -1,7 +1,14 @@ import { AnyObject } from '../types/basic' import { getVueConstructor } from '../runtimeContext' -import { isArray, isPrimitive, isUndef, isValidArrayIndex } from '../utils' -import { defineAccessControl } from './reactive' +import { + isArray, + isPrimitive, + isUndef, + isValidArrayIndex, + isObject, + hasOwn, +} from '../utils' +import { defineAccessControl, mockReactivityDeep } from './reactive' /** * Set a property on an object. Adds the new property, triggers change @@ -49,6 +56,11 @@ export function set(target: AnyObject, key: any, val: T): T { // IMPORTANT: define access control before trigger watcher defineAccessControl(target, key, val) + // in SSR, there is no __ob__. Mock for reactivity check + if (isObject(target[key]) && !hasOwn(target[key], '__ob__')) { + mockReactivityDeep(target[key]) + } + ob.dep.notify() return val } diff --git a/test/ssr/ssrReactive.spec.ts b/test/ssr/ssrReactive.spec.ts index 90ec277a..432244be 100644 --- a/test/ssr/ssrReactive.spec.ts +++ b/test/ssr/ssrReactive.spec.ts @@ -145,4 +145,11 @@ describe('SSR Reactive', () => { `"RangeError: Maximum call stack size exceeded"` ).not.toHaveBeenWarned() }) + + it('should work on objects sets with set()', () => { + const state = ref({}) + set(state.value, 'a', {}) + + expect(isReactive(state.value.a)).toBe(true) + }) })