Replacing an array within a reactive with a copy breaks .indexOf
Vue version
3.2.36
Link to minimal reproduction
Steps to reproduce
The expected and actual outcomes are logged to the console
What is expected?
When making a copy of an array within a Reactive
and plugging it back into the reactive, I expect that .indexOf
will still behave correctly
What is actually happening?
When .slice
is called on the array within the reactive, Vue turns it into an Array<Proxy<Object>>
, to avoid losing reactivity on the items. When this result is then plugged back into the reactive, those proxied objects remain in the array.
When .indexOf
is called with a non-proxied object, it will return -1
, as the non-proxied object isn't identity-equal to the proxied one.
createArrayInstumentations already contains a branch for when an operation is called with a proxied argument on an array without proxied objects. My case is the exact opposite: an operation is called with a non-proxied argument on an array with proxied objects.
Changing return arr[key](...args.map(toRaw))
to return arr.map(toRaw)[key](...args.map(toRaw))
makes my test case pass.
System Info
No response
Any additional comments?
I ran into this when writing unit tests. I have constant test data, which I made reactive for a test case in a similar way as in the reproduction. Initially, .indexOf
worked for searching the array within the reactive, but it failed after changing items in the reactive's array by making a defensive copy.
option 1
state.items = [...toRaw(state.items), item2];
option 2
state.items.map(toRaw).indexOf(item1)
option 3
don't mix and match raw and reactive playground reactive only