Skip to content

Commit bf33217

Browse files
authored
fix(reactivity): avoid wrapping extended array methods (vuejs#11572)
close vuejs#11570
1 parent 6acb046 commit bf33217

File tree

2 files changed

+25
-2
lines changed

2 files changed

+25
-2
lines changed

packages/reactivity/__tests__/reactiveArray.spec.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -622,5 +622,22 @@ describe('reactivity/reactive/Array', () => {
622622
const firstItem = Array.from(deep.values())[0]
623623
expect(isReactive(firstItem)).toBe(true)
624624
})
625+
626+
test('extend methods', () => {
627+
class Collection extends Array {
628+
find(id: any) {
629+
return super.find(obj => obj.id === id)
630+
}
631+
}
632+
633+
const state = reactive({
634+
things: new Collection(),
635+
})
636+
637+
const val = { id: 'foo', value: 'bar' }
638+
state.things.push(val)
639+
640+
expect(state.things.find('foo')).toBe(val)
641+
})
625642
})
626643
})

packages/reactivity/src/arrayInstrumentations.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,7 @@ function iterator(
227227
// higher than that
228228
type ArrayMethods = keyof Array<any> | 'findLast' | 'findLastIndex'
229229

230+
const arrayProto = Array.prototype
230231
// instrument functions that read (potentially) all items
231232
// to take ARRAY_ITERATE dependency
232233
function apply(
@@ -237,6 +238,12 @@ function apply(
237238
wrappedRetFn?: (result: any) => unknown,
238239
) {
239240
const arr = shallowReadArray(self)
241+
let methodFn
242+
// @ts-expect-error our code is limited to es2016 but user code is not
243+
if ((methodFn = arr[method]) !== arrayProto[method]) {
244+
return methodFn.apply(arr, arrayProto.slice.call(arguments, 2))
245+
}
246+
240247
let needsWrap = false
241248
let wrappedFn = fn
242249
if (arr !== self) {
@@ -251,8 +258,7 @@ function apply(
251258
}
252259
}
253260
}
254-
// @ts-expect-error our code is limited to es2016 but user code is not
255-
const result = arr[method](wrappedFn, thisArg)
261+
const result = methodFn.call(arr, wrappedFn, thisArg)
256262
return needsWrap && wrappedRetFn ? wrappedRetFn(result) : result
257263
}
258264

0 commit comments

Comments
 (0)