feat(reactivity): add shallowReactive function (#689)
This commit is contained in:
parent
2d56dfdc4f
commit
7f38c1e0ff
@ -1,5 +1,11 @@
|
|||||||
import { ref, isRef } from '../src/ref'
|
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 { mockWarn } from '@vue/shared'
|
||||||
import { computed } from '../src/computed'
|
import { computed } from '../src/computed'
|
||||||
|
|
||||||
@ -212,4 +218,17 @@ describe('reactivity/reactive', () => {
|
|||||||
expect(isReactive(obj.foo)).toBe(true)
|
expect(isReactive(obj.foo)).toBe(true)
|
||||||
expect(isReactive(obj.bar)).toBe(false)
|
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)
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
@ -12,6 +12,7 @@ const builtInSymbols = new Set(
|
|||||||
)
|
)
|
||||||
|
|
||||||
const get = /*#__PURE__*/ createGetter()
|
const get = /*#__PURE__*/ createGetter()
|
||||||
|
const shallowReactiveGet = /*#__PURE__*/ createGetter(false, true)
|
||||||
const readonlyGet = /*#__PURE__*/ createGetter(true)
|
const readonlyGet = /*#__PURE__*/ createGetter(true)
|
||||||
const shallowReadonlyGet = /*#__PURE__*/ createGetter(true, true)
|
const shallowReadonlyGet = /*#__PURE__*/ createGetter(true, true)
|
||||||
|
|
||||||
@ -54,6 +55,7 @@ function createGetter(isReadonly = false, shallow = false) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const set = /*#__PURE__*/ createSetter()
|
const set = /*#__PURE__*/ createSetter()
|
||||||
|
const shallowReactiveSet = /*#__PURE__*/ createSetter(false, true)
|
||||||
const readonlySet = /*#__PURE__*/ createSetter(true)
|
const readonlySet = /*#__PURE__*/ createSetter(true)
|
||||||
const shallowReadonlySet = /*#__PURE__*/ createSetter(true, true)
|
const shallowReadonlySet = /*#__PURE__*/ createSetter(true, true)
|
||||||
|
|
||||||
@ -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
|
// 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
|
// refs (in order to allow refs to be explicitly passed down), but should
|
||||||
// retain the reactivity of the normal readonly object.
|
// retain the reactivity of the normal readonly object.
|
||||||
|
@ -2,6 +2,7 @@ export { ref, isRef, toRefs, Ref, UnwrapRef } from './ref'
|
|||||||
export {
|
export {
|
||||||
reactive,
|
reactive,
|
||||||
isReactive,
|
isReactive,
|
||||||
|
shallowReactive,
|
||||||
readonly,
|
readonly,
|
||||||
isReadonly,
|
isReadonly,
|
||||||
shallowReadonly,
|
shallowReadonly,
|
||||||
|
@ -2,7 +2,8 @@ import { isObject, toRawType } from '@vue/shared'
|
|||||||
import {
|
import {
|
||||||
mutableHandlers,
|
mutableHandlers,
|
||||||
readonlyHandlers,
|
readonlyHandlers,
|
||||||
shallowReadonlyHandlers
|
shallowReadonlyHandlers,
|
||||||
|
shallowReactiveHandlers
|
||||||
} from './baseHandlers'
|
} from './baseHandlers'
|
||||||
import {
|
import {
|
||||||
mutableCollectionHandlers,
|
mutableCollectionHandlers,
|
||||||
@ -75,7 +76,6 @@ export function readonly<T extends object>(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// @internal
|
|
||||||
// Return a reactive-copy of the original object, where only the root level
|
// Return a reactive-copy of the original object, where only the root level
|
||||||
// properties are readonly, and does NOT unwrap refs nor recursively convert
|
// properties are readonly, and does NOT unwrap refs nor recursively convert
|
||||||
// returned properties.
|
// returned properties.
|
||||||
@ -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(
|
function createReactiveObject(
|
||||||
target: unknown,
|
target: unknown,
|
||||||
toProxy: WeakMap<any, any>,
|
toProxy: WeakMap<any, any>,
|
||||||
|
Loading…
Reference in New Issue
Block a user