fix(reactivity): track hasOwnProperty

fix #2619
close #2621
This commit is contained in:
Evan You 2022-11-14 17:17:35 +08:00
parent ce363e55a8
commit 588bd44f03
2 changed files with 40 additions and 2 deletions

View File

@ -964,5 +964,31 @@ describe('reactivity/effect', () => {
m.set(key, 2)
expect(fnSpy).toHaveBeenCalledTimes(2)
})
test('should track hasOwnProperty', () => {
const obj: any = reactive({})
let has = false
const fnSpy = jest.fn()
effect(() => {
fnSpy()
has = obj.hasOwnProperty('foo')
})
expect(fnSpy).toHaveBeenCalledTimes(1)
expect(has).toBe(false)
obj.foo = 1
expect(fnSpy).toHaveBeenCalledTimes(2)
expect(has).toBe(true)
delete obj.foo
expect(fnSpy).toHaveBeenCalledTimes(3)
expect(has).toBe(false)
// should not trigger on unrelated key
obj.bar = 2
expect(fnSpy).toHaveBeenCalledTimes(3)
expect(has).toBe(false)
})
})
})

View File

@ -85,6 +85,13 @@ function createArrayInstrumentations() {
return instrumentations
}
function hasOwnProperty(key: string) {
// @ts-ignore
const obj = toRaw(this)
track(obj, TrackOpTypes.HAS, key)
return obj.hasOwnProperty(key)
}
function createGetter(isReadonly = false, shallow = false) {
return function get(target: Target, key: string | symbol, receiver: object) {
if (key === ReactiveFlags.IS_REACTIVE) {
@ -110,8 +117,13 @@ function createGetter(isReadonly = false, shallow = false) {
const targetIsArray = isArray(target)
if (!isReadonly && targetIsArray && hasOwn(arrayInstrumentations, key)) {
return Reflect.get(arrayInstrumentations, key, receiver)
if (!isReadonly) {
if (targetIsArray && hasOwn(arrayInstrumentations, key)) {
return Reflect.get(arrayInstrumentations, key, receiver)
}
if (key === 'hasOwnProperty') {
return hasOwnProperty
}
}
const res = Reflect.get(target, key, receiver)