Home > Enterprise >  Vue dynamic array computed from data
Vue dynamic array computed from data

Time:08-18

Say I have this data retrieved from my store:

let itemsData=[
  {id:1,data:[...]},
  {id:2,data:[...]},
  {id:3,data:[...]}
]

I need to be able to produce an array from this data which looks something like this:

let itemsSelected=[
  {id:1,selected:false},
  {id:2,selected:false},
  {id:3,selected:false}
]

And then I need to have this array, itemsSelected, accessible to determine the state of multiple different components in the template, for example:

<div v-for="item in itemsSelected" :key="item.id" :></div>

I originally thought to use a computed property, but I need to be able to dynamically update the selected value of items in itemsSelected. However, I also want the array to be constructed based on data in the store, and it should add/remove items from itemsSelected whenever itemsData changes. How can I achieve these things together?

CodePudding user response:

You could use a watcher to update itemSelected based on itemsData. The following example uses Array.prototype.reduce to create a new map of item IDs to a shallow copy of the original array item plus a selected property:

import { watchEffect, ref, reactive } from 'vue'

let itemsData = reactive([
  { id: 1, data: [newData()] },
  { id: 2, data: [newData()] },
  { id: 3, data: [newData()] },
])

let itemsSelected = ref({})

watchEffect(() => {
  const selections = itemsSelected.value
  itemsSelected.value = itemsData.reduce((p, c) => {
    p[c.id] = {
      ...c,
      selected: selections[c.id]?.selected ?? false,
    }
    return p
  }, {})
})

This allows itemsSelected to still be editable, enabling modification of the selected properties in itemsSelected without affecting itemsData.

demo

  • Related