Vue 3 - The official way to update shallowReactive array

Viewed 3283

I have for example the following array:

setup() {
   let array = shallowReactive([]);
   return {
      array
   };
}

Using of shallow reactive is important, because this array could contains not reactive objects, that in turn can have reactive fields itself. I need to filter its elements. The following code doesn't work because it creates a new object, that has no common with array that used in the template:

array = array.filter(obj => !obj.empty)

The only known to me way that preserves reactivity is:

array.splice(0, array.length, ...array.filter(obj => !obj.empty))

But it looks ugly and possibly is not effective. Are there any other ways that preserves reactivity?

3 Answers

Maybe this will help you?

import { ref, computed } from "vue"
setup() {
   const shallowReactive = ref([{obj:'1'}, {obj:'2'}, {}])
   const array = computed( () =>  shallowReactive.value.filter(obj => obj.obj))
   console.log(array.value)

   return {
      array
   };
}

If you want to change the content of the array, using splice is the cleanest way. (as opposed to push, shift etc.).

It's common to use a computed to have a copy of your array that will have the filtered copy of the array, but that might not be what you're looking for.

Another option is to use a ref or shallowRef instead of the shallowReactive

Unfortunately, AFAIK, there's no way to change the target of the Proxy externally that shallowReactive creates.

I think Object.assign would keep it reactive while being cleaner.

Demo: https://codepen.io/jacobgoh101/pen/RwoZOGr

in your case,


  setup() {
    const array = shallowReactive([]);

    const mutate = () => {
        const newArray = array.filter(obj => !obj.empty);
        Object.assign(array, newArray);
    };

    return {
      array,
      mutate
    };
  }
Related