Composition-api: "reactive" doesn't work well with Array

Created on 31 Dec 2019  路  6Comments  路  Source: vuejs/composition-api

The reactive can't observe a Array, my code like this:

<template>
  <div>
    <button @click="handleAdd">Add count</button>
  </div>
</template>
<script>
import Vue from "vue";
import { setup, reactive, ref, watch } from "@vue/composition-api";

const observableArray = Vue.observable([{ value: 1 }]);

export default {
  setup() {
    const reactiveArray = reactive([{ value: 1 }]);
    const reactiveObject = reactive({ value: 1 });
    const refArray = ref([{ value: 1 }]);
    const reactiveDeepArray = reactive({parent: [{ value: 1 }]})

    watch(
      () => reactiveArray[0].value,
      val => {
        // I think this should be execute when I click the button every time,
        // but it doesn't
        console.log("reactiveArray changed", val);
      }
    );

    watch(
      () => reactiveObject.value,
      val => {
        // This will execute when I click the button every time
        console.log("reactiveObject changed", val);
      }
    );

    watch(
      () => refArray.value[0].value,
      val => {
        // This will execute when I click the button every time
        console.log("refArray changed", val);
      }
    );

    watch(
      () => observableArray[0].value,
      val => {
        // This will execute when I click the button every time
        console.log("observableArray changed", val);
      }
    );

    watch(
      () => reactiveDeepArray.parent[0].value,
      val => {
        // This will execute when I click the button every time
        console.log("reactiveDeepArray changed", val);
      }
    );

    function handleAdd() {
      reactiveArray[0].value++
      reactiveObject.value++
      refArray.value[0].value++
      observableArray[0].value++
      reactiveDeepArray.parent[0].value++
    }

    return {
      handleAdd
    };
  }
};
</script>

So, when I pass a Array to reactive, it won't be observed. But if the Array is wrapped by a object, it can be observed. I think it's a bug. If it's a feature, why?

misalignment

Most helpful comment

reactive should be used on an object, maybe there is a way to make the typing stricter but both object and Record allow setting an array so I don't know if there is another option apart from a runtime warning to help with this

But array is also an object, why can't use reactive just like Vue.observable?

All 6 comments

reactive should be used on an object, maybe there is a way to make the typing stricter but both object and Record allow setting an array so I don't know if there is another option apart from a runtime warning to help with this

reactive should be used on an object, maybe there is a way to make the typing stricter but both object and Record allow setting an array so I don't know if there is another option apart from a runtime warning to help with this

But array is also an object, why can't use reactive just like Vue.observable?

Just make in reactive an object whith an array in it. This works very well. Similiar to the data object in vue 2 before:

setup() {  
let items = reactive({
  list: [ //heres the object which has an array
    { title: "test1", id: 0 },
    { title: "test2", id: 1 },
    { title: "test3", id: 2 }
  ]
});
const deleteItem = childItem => {
  items.list = items.list.filter(item => item.id != childItem.id); //items.list will updated reactively
};
return { deleteItem, items, test };
}

Just make in reactive an object whith an array in it. This works very well. Similiar to the data object in vue 2 before:

setup() {  
let items = reactive({
  list: [ //heres the object which has an array
    { title: "test1", id: 0 },
    { title: "test2", id: 1 },
    { title: "test3", id: 2 }
  ]
});
const deleteItem = childItem => {
  items.list = items.list.filter(item => item.id != childItem.id); //items.list will updated reactively
};
return { deleteItem, items, test };
}

I know this work, but I just want reactive a plain Array

I know this work, but I just want reactive a plain Array

That's literally the ~first~ second limitation on the readme.md.

@pikax #502 seems just made the use of ref in a reactive array unnecessary. I still need the workaround (a reactive object with an array in it) and therefore the original issue has not been fixed yet.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

gokhantaskan picture gokhantaskan  路  6Comments

TooBug picture TooBug  路  6Comments

SeregPie picture SeregPie  路  6Comments

carlmjohnson picture carlmjohnson  路  5Comments

jaryn-kubik picture jaryn-kubik  路  3Comments