Skip to content

Commit

Permalink
feat(reactivity): add shallowReactive function (#689)
Browse files Browse the repository at this point in the history
  • Loading branch information
dsseng authored Feb 4, 2020
1 parent 2d56dfd commit 7f38c1e
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 3 deletions.
21 changes: 20 additions & 1 deletion packages/reactivity/__tests__/reactive.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
import { ref, isRef } from '../src/ref'
import { reactive, isReactive, toRaw, markNonReactive } from '../src/reactive'
import {
reactive,
isReactive,
toRaw,
markNonReactive,
shallowReactive
} from '../src/reactive'
import { mockWarn } from '@vue/shared'
import { computed } from '../src/computed'

Expand Down Expand Up @@ -212,4 +218,17 @@ describe('reactivity/reactive', () => {
expect(isReactive(obj.foo)).toBe(true)
expect(isReactive(obj.bar)).toBe(false)
})

describe('shallowReactive', () => {
test('should not make non-reactive properties reactive', () => {
const props = shallowReactive({ n: { foo: 1 } })
expect(isReactive(props.n)).toBe(false)
})

test('should keep reactive properties reactive', () => {
const props: any = shallowReactive({ n: reactive({ foo: 1 }) })
props.n = reactive({ foo: 2 })
expect(isReactive(props.n)).toBe(true)
})
})
})
8 changes: 8 additions & 0 deletions packages/reactivity/src/baseHandlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ const builtInSymbols = new Set(
)

const get = /*#__PURE__*/ createGetter()
const shallowReactiveGet = /*#__PURE__*/ createGetter(false, true)
const readonlyGet = /*#__PURE__*/ createGetter(true)
const shallowReadonlyGet = /*#__PURE__*/ createGetter(true, true)

Expand Down Expand Up @@ -54,6 +55,7 @@ function createGetter(isReadonly = false, shallow = false) {
}

const set = /*#__PURE__*/ createSetter()
const shallowReactiveSet = /*#__PURE__*/ createSetter(false, true)
const readonlySet = /*#__PURE__*/ createSetter(true)
const shallowReadonlySet = /*#__PURE__*/ createSetter(true, true)

Expand Down Expand Up @@ -165,6 +167,12 @@ export const readonlyHandlers: ProxyHandler<object> = {
}
}

export const shallowReactiveHandlers: ProxyHandler<object> = {
...mutableHandlers,
get: shallowReactiveGet,
set: shallowReactiveSet
}

// Props handlers are special in the sense that it should not unwrap top-level
// refs (in order to allow refs to be explicitly passed down), but should
// retain the reactivity of the normal readonly object.
Expand Down
1 change: 1 addition & 0 deletions packages/reactivity/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ export { ref, isRef, toRefs, Ref, UnwrapRef } from './ref'
export {
reactive,
isReactive,
shallowReactive,
readonly,
isReadonly,
shallowReadonly,
Expand Down
17 changes: 15 additions & 2 deletions packages/reactivity/src/reactive.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import { isObject, toRawType } from '@vue/shared'
import {
mutableHandlers,
readonlyHandlers,
shallowReadonlyHandlers
shallowReadonlyHandlers,
shallowReactiveHandlers
} from './baseHandlers'
import {
mutableCollectionHandlers,
Expand Down Expand Up @@ -75,7 +76,6 @@ export function readonly<T extends object>(
)
}

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

// Return a reactive-copy of the original object, where only the root level
// properties are reactive, and does NOT unwrap refs nor recursively convert
// returned properties.
export function shallowReactive<T extends object>(target: T): T {
return createReactiveObject(
target,
rawToReactive,
reactiveToRaw,
shallowReactiveHandlers,
mutableCollectionHandlers
)
}

function createReactiveObject(
target: unknown,
toProxy: WeakMap<any, any>,
Expand Down

0 comments on commit 7f38c1e

Please sign in to comment.