Searching a reactive array in Vue.js 3

Viewed 2071

In Vue.js 3 (beta), I have defined an array using reactive, as I want to bind its contents to some UI controls in a loop. So far, this works and everything is fine.

Now, I need to update a value within this array, which means I need to run a find or a findIndex on this array. Since the array is being proxied by Vue.js, this doesn't work as expected: The proxy is just not a simple plain old array.

What I did is get a copy using toRaw, run findIndex on that one, and then update the original array using the index. This works, but of course it doesn't seem to be very elegant.

Is there a better way to approach this?

PS: It's fine if it's a solution that only works in Vue 3, I don't care about the 2.x series.

1 Answers

All the array's methods are still accessible through the Proxy, so you can still use find or findIndex on it:

import { reactive } from 'vue'

const items = reactive([1,2,3])

console.log(items.find(x => x % 2 === 0))
console.log(items.findIndex(x => x % 2 === 0))

const MyApp = {
  setup() {
    const items = Vue.reactive([1,2,3])
    
    return {
      items,
      addItem() {
        items.push(items.length + 1)
      },
      logFirstEvenValue() {
        console.log(items.find(x => x % 2 === 0))
      },
      logFirstEvenIndex() {
        console.log(items.findIndex(x => x % 2 === 0))
      },
      incrementItems() {
        for (let i = 0; i < items.length; i++) {
          items[i]++
        }
      }
    }
  }
}

Vue.createApp(MyApp).mount('#app')
<script src="https://unpkg.com/vue@3.0.0-rc.5"></script>
<div id="app">
  <button @click="logFirstEvenValue">Log first even item</button>
  <button @click="logFirstEvenIndex">Log index of first even item</button>
  <button @click="incrementItems">Increment items</button>
  <button @click="addItem">Add item</button>
  <ul>
    <li v-for="item in items">{{item}}</li>
  </ul>
</div>

Related