parent
							
								
									2dcdbca6e2
								
							
						
					
					
						commit
						0a4f306492
					
				@ -470,5 +470,13 @@ describe('reactivity/readonly', () => {
 | 
				
			|||||||
        `Set operation on key "foo" failed: target is readonly.`
 | 
					        `Set operation on key "foo" failed: target is readonly.`
 | 
				
			||||||
      ).not.toHaveBeenWarned()
 | 
					      ).not.toHaveBeenWarned()
 | 
				
			||||||
    })
 | 
					    })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    test('should keep reactive properties reactive', () => {
 | 
				
			||||||
 | 
					      const props: any = shallowReadonly({ n: reactive({ foo: 1 }) })
 | 
				
			||||||
 | 
					      unlock()
 | 
				
			||||||
 | 
					      props.n = reactive({ foo: 2 })
 | 
				
			||||||
 | 
					      lock()
 | 
				
			||||||
 | 
					      expect(isReactive(props.n)).toBe(true)
 | 
				
			||||||
 | 
					    })
 | 
				
			||||||
  })
 | 
					  })
 | 
				
			||||||
})
 | 
					})
 | 
				
			||||||
 | 
				
			|||||||
@ -11,7 +11,11 @@ const builtInSymbols = new Set(
 | 
				
			|||||||
    .filter(isSymbol)
 | 
					    .filter(isSymbol)
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function createGetter(isReadonly: boolean, shallow = false) {
 | 
					const get = createGetter()
 | 
				
			||||||
 | 
					const readonlyGet = createGetter(true)
 | 
				
			||||||
 | 
					const shallowReadonlyGet = createGetter(true, true)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function createGetter(isReadonly = false, shallow = false) {
 | 
				
			||||||
  return function get(target: object, key: string | symbol, receiver: object) {
 | 
					  return function get(target: object, key: string | symbol, receiver: object) {
 | 
				
			||||||
    const res = Reflect.get(target, key, receiver)
 | 
					    const res = Reflect.get(target, key, receiver)
 | 
				
			||||||
    if (isSymbol(key) && builtInSymbols.has(key)) {
 | 
					    if (isSymbol(key) && builtInSymbols.has(key)) {
 | 
				
			||||||
@ -36,18 +40,38 @@ function createGetter(isReadonly: boolean, shallow = false) {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function set(
 | 
					const set = createSetter()
 | 
				
			||||||
 | 
					const readonlySet = createSetter(true)
 | 
				
			||||||
 | 
					const shallowReadonlySet = createSetter(true, true)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function createSetter(isReadonly = false, shallow = false) {
 | 
				
			||||||
 | 
					  return function set(
 | 
				
			||||||
    target: object,
 | 
					    target: object,
 | 
				
			||||||
    key: string | symbol,
 | 
					    key: string | symbol,
 | 
				
			||||||
    value: unknown,
 | 
					    value: unknown,
 | 
				
			||||||
    receiver: object
 | 
					    receiver: object
 | 
				
			||||||
): boolean {
 | 
					  ): boolean {
 | 
				
			||||||
  value = toRaw(value)
 | 
					    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]
 | 
					    const oldValue = (target as any)[key]
 | 
				
			||||||
 | 
					    if (!shallow) {
 | 
				
			||||||
 | 
					      value = toRaw(value)
 | 
				
			||||||
      if (isRef(oldValue) && !isRef(value)) {
 | 
					      if (isRef(oldValue) && !isRef(value)) {
 | 
				
			||||||
        oldValue.value = value
 | 
					        oldValue.value = value
 | 
				
			||||||
        return true
 | 
					        return true
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      // in shallow mode, objects are set as-is regardless of reactive or not
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const hadKey = hasOwn(target, key)
 | 
					    const hadKey = hasOwn(target, key)
 | 
				
			||||||
    const result = Reflect.set(target, key, value, receiver)
 | 
					    const result = Reflect.set(target, key, value, receiver)
 | 
				
			||||||
    // don't trigger if target is something up in the prototype chain of original
 | 
					    // don't trigger if target is something up in the prototype chain of original
 | 
				
			||||||
@ -69,6 +93,7 @@ function set(
 | 
				
			|||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return result
 | 
					    return result
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function deleteProperty(target: object, key: string | symbol): boolean {
 | 
					function deleteProperty(target: object, key: string | symbol): boolean {
 | 
				
			||||||
@ -98,7 +123,7 @@ function ownKeys(target: object): (string | number | symbol)[] {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const mutableHandlers: ProxyHandler<object> = {
 | 
					export const mutableHandlers: ProxyHandler<object> = {
 | 
				
			||||||
  get: createGetter(false),
 | 
					  get,
 | 
				
			||||||
  set,
 | 
					  set,
 | 
				
			||||||
  deleteProperty,
 | 
					  deleteProperty,
 | 
				
			||||||
  has,
 | 
					  has,
 | 
				
			||||||
@ -106,27 +131,10 @@ export const mutableHandlers: ProxyHandler<object> = {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const readonlyHandlers: ProxyHandler<object> = {
 | 
					export const readonlyHandlers: ProxyHandler<object> = {
 | 
				
			||||||
  get: createGetter(true),
 | 
					  get: readonlyGet,
 | 
				
			||||||
 | 
					  set: readonlySet,
 | 
				
			||||||
  set(
 | 
					  has,
 | 
				
			||||||
    target: object,
 | 
					  ownKeys,
 | 
				
			||||||
    key: string | symbol,
 | 
					 | 
				
			||||||
    value: unknown,
 | 
					 | 
				
			||||||
    receiver: object
 | 
					 | 
				
			||||||
  ): boolean {
 | 
					 | 
				
			||||||
    if (LOCKED) {
 | 
					 | 
				
			||||||
      if (__DEV__) {
 | 
					 | 
				
			||||||
        console.warn(
 | 
					 | 
				
			||||||
          `Set operation on key "${String(key)}" failed: target is readonly.`,
 | 
					 | 
				
			||||||
          target
 | 
					 | 
				
			||||||
        )
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      return true
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
      return set(target, key, value, receiver)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  deleteProperty(target: object, key: string | symbol): boolean {
 | 
					  deleteProperty(target: object, key: string | symbol): boolean {
 | 
				
			||||||
    if (LOCKED) {
 | 
					    if (LOCKED) {
 | 
				
			||||||
      if (__DEV__) {
 | 
					      if (__DEV__) {
 | 
				
			||||||
@ -141,10 +149,7 @@ export const readonlyHandlers: ProxyHandler<object> = {
 | 
				
			|||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
      return deleteProperty(target, key)
 | 
					      return deleteProperty(target, key)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  },
 | 
					  }
 | 
				
			||||||
 | 
					 | 
				
			||||||
  has,
 | 
					 | 
				
			||||||
  ownKeys
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 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
 | 
				
			||||||
@ -152,5 +157,6 @@ export const readonlyHandlers: ProxyHandler<object> = {
 | 
				
			|||||||
// retain the reactivity of the normal readonly object.
 | 
					// retain the reactivity of the normal readonly object.
 | 
				
			||||||
export const shallowReadonlyHandlers: ProxyHandler<object> = {
 | 
					export const shallowReadonlyHandlers: ProxyHandler<object> = {
 | 
				
			||||||
  ...readonlyHandlers,
 | 
					  ...readonlyHandlers,
 | 
				
			||||||
  get: createGetter(true, true)
 | 
					  get: shallowReadonlyGet,
 | 
				
			||||||
 | 
					  set: shallowReadonlySet
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user