@@ -8,7 +8,13 @@ import {
8
8
reactiveMap
9
9
} from './reactive'
10
10
import { TrackOpTypes , TriggerOpTypes } from './operations'
11
- import { track , trigger , ITERATE_KEY } from './effect'
11
+ import {
12
+ track ,
13
+ trigger ,
14
+ ITERATE_KEY ,
15
+ pauseTracking ,
16
+ enableTracking
17
+ } from './effect'
12
18
import {
13
19
isObject ,
14
20
hasOwn ,
@@ -32,22 +38,36 @@ const readonlyGet = /*#__PURE__*/ createGetter(true)
32
38
const shallowReadonlyGet = /*#__PURE__*/ createGetter ( true , true )
33
39
34
40
const arrayInstrumentations : Record < string , Function > = { }
41
+ // instrument identity-sensitive Array methods to account for possible reactive
42
+ // values
35
43
; ( [ 'includes' , 'indexOf' , 'lastIndexOf' ] as const ) . forEach ( key => {
44
+ const method = Array . prototype [ key ] as any
36
45
arrayInstrumentations [ key ] = function ( this : unknown [ ] , ...args : unknown [ ] ) {
37
46
const arr = toRaw ( this )
38
47
for ( let i = 0 , l = this . length ; i < l ; i ++ ) {
39
48
track ( arr , TrackOpTypes . GET , i + '' )
40
49
}
41
50
// we run the method using the original args first (which may be reactive)
42
- const res = ( arr [ key ] as any ) ( ... args )
51
+ const res = method . apply ( arr , args )
43
52
if ( res === - 1 || res === false ) {
44
53
// if that didn't work, run it again using raw values.
45
- return ( arr [ key ] as any ) ( ... args . map ( toRaw ) )
54
+ return method . apply ( arr , args . map ( toRaw ) )
46
55
} else {
47
56
return res
48
57
}
49
58
}
50
59
} )
60
+ // instrument length-altering mutation methods to avoid length being tracked
61
+ // which leads to infinite loops in some cases (#2137)
62
+ ; ( [ 'push' , 'pop' , 'shift' , 'unshift' , 'splice' ] as const ) . forEach ( key => {
63
+ const method = Array . prototype [ key ] as any
64
+ arrayInstrumentations [ key ] = function ( this : unknown [ ] , ...args : unknown [ ] ) {
65
+ pauseTracking ( )
66
+ const res = method . apply ( this , args )
67
+ enableTracking ( )
68
+ return res
69
+ }
70
+ } )
51
71
52
72
function createGetter ( isReadonly = false , shallow = false ) {
53
73
return function get ( target : Target , key : string | symbol , receiver : object ) {
0 commit comments