refactor(reactivity): make readonly non-tracking
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
import { reactive, readonly, toRaw } from './reactive'
|
||||
import { TrackOpTypes, TriggerOpTypes } from './operations'
|
||||
import { track, trigger, ITERATE_KEY } from './effect'
|
||||
import { LOCKED } from './lock'
|
||||
import { isObject, hasOwn, isSymbol, hasChanged, isArray } from '@vue/shared'
|
||||
import { isRef } from './ref'
|
||||
|
||||
@@ -12,7 +11,7 @@ const builtInSymbols = new Set(
|
||||
)
|
||||
|
||||
const get = /*#__PURE__*/ createGetter()
|
||||
const shallowReactiveGet = /*#__PURE__*/ createGetter(false, true)
|
||||
const shallowGet = /*#__PURE__*/ createGetter(false, true)
|
||||
const readonlyGet = /*#__PURE__*/ createGetter(true)
|
||||
const shallowReadonlyGet = /*#__PURE__*/ createGetter(true, true)
|
||||
|
||||
@@ -41,57 +40,47 @@ function createGetter(isReadonly = false, shallow = false) {
|
||||
return Reflect.get(arrayInstrumentations, key, receiver)
|
||||
}
|
||||
const res = Reflect.get(target, key, receiver)
|
||||
|
||||
if (isSymbol(key) && builtInSymbols.has(key)) {
|
||||
return res
|
||||
}
|
||||
|
||||
if (shallow) {
|
||||
track(target, TrackOpTypes.GET, key)
|
||||
// TODO strict mode that returns a shallow-readonly version of the value
|
||||
!isReadonly && track(target, TrackOpTypes.GET, key)
|
||||
return res
|
||||
}
|
||||
|
||||
if (isRef(res)) {
|
||||
if (targetIsArray) {
|
||||
track(target, TrackOpTypes.GET, key)
|
||||
!isReadonly && track(target, TrackOpTypes.GET, key)
|
||||
return res
|
||||
} else {
|
||||
// ref unwrapping, only for Objects, not for Arrays.
|
||||
return res.value
|
||||
}
|
||||
} else {
|
||||
track(target, TrackOpTypes.GET, key)
|
||||
return isObject(res)
|
||||
? isReadonly
|
||||
? // need to lazy access readonly and reactive here to avoid
|
||||
// circular dependency
|
||||
readonly(res)
|
||||
: reactive(res)
|
||||
: res
|
||||
}
|
||||
|
||||
!isReadonly && track(target, TrackOpTypes.GET, key)
|
||||
return isObject(res)
|
||||
? isReadonly
|
||||
? // need to lazy access readonly and reactive here to avoid
|
||||
// circular dependency
|
||||
readonly(res)
|
||||
: reactive(res)
|
||||
: res
|
||||
}
|
||||
}
|
||||
|
||||
const set = /*#__PURE__*/ createSetter()
|
||||
const shallowReactiveSet = /*#__PURE__*/ createSetter(false, true)
|
||||
const readonlySet = /*#__PURE__*/ createSetter(true)
|
||||
const shallowReadonlySet = /*#__PURE__*/ createSetter(true, true)
|
||||
const shallowSet = /*#__PURE__*/ createSetter(true)
|
||||
|
||||
function createSetter(isReadonly = false, shallow = false) {
|
||||
function createSetter(shallow = false) {
|
||||
return function set(
|
||||
target: object,
|
||||
key: string | symbol,
|
||||
value: unknown,
|
||||
receiver: object
|
||||
): boolean {
|
||||
if (isReadonly && LOCKED) {
|
||||
if (__DEV__) {
|
||||
console.warn(
|
||||
`Set operation on key "${String(key)}" failed: target is readonly.`,
|
||||
target
|
||||
)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
const oldValue = (target as any)[key]
|
||||
if (!shallow) {
|
||||
value = toRaw(value)
|
||||
@@ -148,30 +137,32 @@ export const mutableHandlers: ProxyHandler<object> = {
|
||||
|
||||
export const readonlyHandlers: ProxyHandler<object> = {
|
||||
get: readonlyGet,
|
||||
set: readonlySet,
|
||||
has,
|
||||
ownKeys,
|
||||
deleteProperty(target: object, key: string | symbol): boolean {
|
||||
if (LOCKED) {
|
||||
if (__DEV__) {
|
||||
console.warn(
|
||||
`Delete operation on key "${String(
|
||||
key
|
||||
)}" failed: target is readonly.`,
|
||||
target
|
||||
)
|
||||
}
|
||||
return true
|
||||
} else {
|
||||
return deleteProperty(target, key)
|
||||
set(target, key) {
|
||||
if (__DEV__) {
|
||||
console.warn(
|
||||
`Set operation on key "${String(key)}" failed: target is readonly.`,
|
||||
target
|
||||
)
|
||||
}
|
||||
return true
|
||||
},
|
||||
deleteProperty(target, key) {
|
||||
if (__DEV__) {
|
||||
console.warn(
|
||||
`Delete operation on key "${String(key)}" failed: target is readonly.`,
|
||||
target
|
||||
)
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
export const shallowReactiveHandlers: ProxyHandler<object> = {
|
||||
...mutableHandlers,
|
||||
get: shallowReactiveGet,
|
||||
set: shallowReactiveSet
|
||||
get: shallowGet,
|
||||
set: shallowSet
|
||||
}
|
||||
|
||||
// Props handlers are special in the sense that it should not unwrap top-level
|
||||
@@ -179,6 +170,5 @@ export const shallowReactiveHandlers: ProxyHandler<object> = {
|
||||
// retain the reactivity of the normal readonly object.
|
||||
export const shallowReadonlyHandlers: ProxyHandler<object> = {
|
||||
...readonlyHandlers,
|
||||
get: shallowReadonlyGet,
|
||||
set: shallowReadonlySet
|
||||
get: shallowReadonlyGet
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user