@@ -8,7 +8,13 @@ import {
88 reactiveMap
99} from './reactive'
1010import { 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'
1218import {
1319 isObject ,
1420 hasOwn ,
@@ -32,22 +38,36 @@ const readonlyGet = /*#__PURE__*/ createGetter(true)
3238const shallowReadonlyGet = /*#__PURE__*/ createGetter ( true , true )
3339
3440const arrayInstrumentations : Record < string , Function > = { }
41+ // instrument identity-sensitive Array methods to account for possible reactive
42+ // values
3543; ( [ 'includes' , 'indexOf' , 'lastIndexOf' ] as const ) . forEach ( key => {
44+ const method = Array . prototype [ key ] as any
3645 arrayInstrumentations [ key ] = function ( this : unknown [ ] , ...args : unknown [ ] ) {
3746 const arr = toRaw ( this )
3847 for ( let i = 0 , l = this . length ; i < l ; i ++ ) {
3948 track ( arr , TrackOpTypes . GET , i + '' )
4049 }
4150 // 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 )
4352 if ( res === - 1 || res === false ) {
4453 // 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 ) )
4655 } else {
4756 return res
4857 }
4958 }
5059} )
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+ } )
5171
5272function createGetter ( isReadonly = false , shallow = false ) {
5373 return function get ( target : Target , key : string | symbol , receiver : object ) {
0 commit comments