Petru Lebada
Petru Lebada

Reputation: 1682

Vue 3 Array state change doesn't trigger watcher

I have a table with a checkbox for each row and a head checkbox which selects all of them, when any checkbox state is changed, it should trigger an event but for some reason when i use the main checkbox to check them all, the watcher doesn't get triggered until i unchecked it:

template:

<table>
 <thead>
  <tr>
   <th>
    <input
     type="checkbox"
     class="form-check-input widget-9-check"
     :name="name"
     v-model="areAllItemsSelected"
    />
   </th>
  </tr>
 </thead>
 <tbody>
  <tr v-for="..."> //here is rowIndex
   <td>
    <input
     type="checkbox"
     class="form-check-input widget-9-check"
     :value="rowIndex"
     v-model="selectedItems"
    />
   </td>
  </tr>
 </tbody>
</table>

setup:

setup(props, {emit}) {
    const selectedItems = ref([])
    const areAllItemsSelected = ref(false)

    watch(areAllItemsSelected, (newValue) => {
      if(newValue) {
        items.value.forEach((item, index) => {
          selectedItems.value.push(index) //this should trigger the below watcher
        })
      } else {
        selectedItems.value = []
      }

    })

    watch(selectedItems, (newValue) => { //this doesn't run when areAllItemsSelected is checked, only when is unchecked
      emit('itemSelected', newValue)
    })

    return {
      items,
      selectedItems,
      areAllItemsSelected
    }
  }

Upvotes: 3

Views: 4252

Answers (1)

tony19
tony19

Reputation: 138696

Vue 3 requires the deep watcher flag when watching arrays. Pass the deep flag in the third argument of watch():

watch(selectedItems, (newValue) => {/*...*/}, { deep: true })
                                                  👆

demo

Upvotes: 15

Related Questions