Skip to content

Commit 7f38c1e

Browse files
authored
feat(reactivity): add shallowReactive function (#689)
1 parent 2d56dfd commit 7f38c1e

File tree

4 files changed

+44
-3
lines changed

4 files changed

+44
-3
lines changed

packages/reactivity/__tests__/reactive.spec.ts

+20-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
import { ref, isRef } from '../src/ref'
2-
import { reactive, isReactive, toRaw, markNonReactive } from '../src/reactive'
2+
import {
3+
reactive,
4+
isReactive,
5+
toRaw,
6+
markNonReactive,
7+
shallowReactive
8+
} from '../src/reactive'
39
import { mockWarn } from '@vue/shared'
410
import { computed } from '../src/computed'
511

@@ -212,4 +218,17 @@ describe('reactivity/reactive', () => {
212218
expect(isReactive(obj.foo)).toBe(true)
213219
expect(isReactive(obj.bar)).toBe(false)
214220
})
221+
222+
describe('shallowReactive', () => {
223+
test('should not make non-reactive properties reactive', () => {
224+
const props = shallowReactive({ n: { foo: 1 } })
225+
expect(isReactive(props.n)).toBe(false)
226+
})
227+
228+
test('should keep reactive properties reactive', () => {
229+
const props: any = shallowReactive({ n: reactive({ foo: 1 }) })
230+
props.n = reactive({ foo: 2 })
231+
expect(isReactive(props.n)).toBe(true)
232+
})
233+
})
215234
})

packages/reactivity/src/baseHandlers.ts

+8
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ const builtInSymbols = new Set(
1212
)
1313

1414
const get = /*#__PURE__*/ createGetter()
15+
const shallowReactiveGet = /*#__PURE__*/ createGetter(false, true)
1516
const readonlyGet = /*#__PURE__*/ createGetter(true)
1617
const shallowReadonlyGet = /*#__PURE__*/ createGetter(true, true)
1718

@@ -54,6 +55,7 @@ function createGetter(isReadonly = false, shallow = false) {
5455
}
5556

5657
const set = /*#__PURE__*/ createSetter()
58+
const shallowReactiveSet = /*#__PURE__*/ createSetter(false, true)
5759
const readonlySet = /*#__PURE__*/ createSetter(true)
5860
const shallowReadonlySet = /*#__PURE__*/ createSetter(true, true)
5961

@@ -165,6 +167,12 @@ export const readonlyHandlers: ProxyHandler<object> = {
165167
}
166168
}
167169

170+
export const shallowReactiveHandlers: ProxyHandler<object> = {
171+
...mutableHandlers,
172+
get: shallowReactiveGet,
173+
set: shallowReactiveSet
174+
}
175+
168176
// Props handlers are special in the sense that it should not unwrap top-level
169177
// refs (in order to allow refs to be explicitly passed down), but should
170178
// retain the reactivity of the normal readonly object.

packages/reactivity/src/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ export { ref, isRef, toRefs, Ref, UnwrapRef } from './ref'
22
export {
33
reactive,
44
isReactive,
5+
shallowReactive,
56
readonly,
67
isReadonly,
78
shallowReadonly,

packages/reactivity/src/reactive.ts

+15-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ import { isObject, toRawType } from '@vue/shared'
22
import {
33
mutableHandlers,
44
readonlyHandlers,
5-
shallowReadonlyHandlers
5+
shallowReadonlyHandlers,
6+
shallowReactiveHandlers
67
} from './baseHandlers'
78
import {
89
mutableCollectionHandlers,
@@ -75,7 +76,6 @@ export function readonly<T extends object>(
7576
)
7677
}
7778

78-
// @internal
7979
// Return a reactive-copy of the original object, where only the root level
8080
// properties are readonly, and does NOT unwrap refs nor recursively convert
8181
// returned properties.
@@ -92,6 +92,19 @@ export function shallowReadonly<T extends object>(
9292
)
9393
}
9494

95+
// Return a reactive-copy of the original object, where only the root level
96+
// properties are reactive, and does NOT unwrap refs nor recursively convert
97+
// returned properties.
98+
export function shallowReactive<T extends object>(target: T): T {
99+
return createReactiveObject(
100+
target,
101+
rawToReactive,
102+
reactiveToRaw,
103+
shallowReactiveHandlers,
104+
mutableCollectionHandlers
105+
)
106+
}
107+
95108
function createReactiveObject(
96109
target: unknown,
97110
toProxy: WeakMap<any, any>,

0 commit comments

Comments
 (0)