Subscribe on changes!

The rewriting of indexOf, including, and lastIndexOf in arrayInstrumentations may have created additional dependency collection.

avatar
Jul 12th 2023

What problem does this feature solve?

example

<script setup>
import { reactive } from 'vue'
const arr = ['a', 'b', 'c', 'd']
const arrproxy = reactive(arr)
</script>

<template>
  <h1>{{ arrproxy.indexOf('d', 2) }}</h1>
</template>

Description

image According to the current rewrite logic, it will traverse the arr and track each item of the arr. That is, the depsMap size corresponding to arr in targetMap is 5; The keys are length, 0, 1, 2, and 3 respectively. But 0, 1 is not necessary to track, because the second parameter of indexOf is 2.

What does the proposed API look like?

Consider the second argument of indexOf, including, and lastIndexOf, the targeted traversal track.

avatar
Jul 12th 2023

If this is an optimization point that needs to be modified, hopefully you can assign it to me to complete.

avatar
Jul 12th 2023

I'm not quite sure what you're trying to convey, but perhaps what you need is cloneDeep.

avatar
Jul 13th 2023

What I want to express is that the indexOf, including lastIndexOf, traversed through each track of the group, creates an additional collection of dependencies. For example, indexOf('d', 2), indexes 0 and 1 should not collect dependencies.

;(['includes', 'indexOf', 'lastIndexOf'] as const).forEach(key => {
    instrumentations[key] = function (this: unknown[], ...args: unknown[]) {
      const arr = toRaw(this) as any
      for (let i = 0, l = this.length; i < l; i++) {
        track(arr, TrackOpTypes.GET, i + '')
      }
      // we run the method using the original args first (which may be reactive)
      const res = arr[key](...args)
      if (res === -1 || res === false) {
        // if that didn't work, run it again using raw values.
        return arr[key](...args.map(toRaw))
      } else {
        return res
      }
    }
  })
avatar
Jul 14th 2023

PR welcome