10

I'm trying to use a reactive array in a component. It works with an object but not with an array of objects.

How can I update the view when the array is updated?

var self = currentClassInstance // this
 
self.store = {
    resources: Vue.reactive([]),
    test:  Vue.reactive({ test: 'my super test' }),

    setResources(resources) {
        // this one doesn't update the view. ?
        this.resources = resources

    }, 
    setResources(resources) {
        // this one update the view
        this.test.test = "test ok"
    },  
}


....

const app_draw = {
    data() {
        return {
            resources: self.store.resources,
            test: self.store.test,
        }
    },
       
    updated() {
        // triggered for "test" but not for "resources"
        console.log('updated')
    },
       
    template: '<div v-for="(resource, key) in resources" :data-key="key">{{resource.name}}</div>'
};
....
1
  • I'll try with Proxies... this.resources = resources erase Vue.reactive, it can't works Commented Oct 18, 2020 at 18:35

4 Answers 4

10

According to the official docs :

Reactive:
Takes an object and returns a reactive proxy of the original. This is equivalent to 2.x's Vue.observable()
....
The reactive conversion is "deep": it affects all nested properties. In the ES2015 Proxy based implementation, the returned proxy is not equal to the original object. It is recommended to work exclusively with the reactive proxy and avoid relying on the original object.

i suggest to assign the array to field called value inside the reactive parameter like you did with test :

resources: Vue.reactive({value:[]}),

then use resources.value=someVal to update that value.

Sign up to request clarification or add additional context in comments.

Comments

5

A quick way

const resources = reactive([]);

// set resources
resources.length = 0;
resources.push(...items)

Comments

3

Adding to the answers above, there are two main ways to handle reactive arrays

Single array with mutating values

const arr = reactive([])
arr.length = 0  // clear
arr.push(...items)

Changing array reference to immutable values

const arr = ref([]) // equivalent to reactive({value:[]})
arr.value = ["Shiver", "me", "timbers"]

Both will trigger reactive updates

Comments

2

Two things:

  • resources: Vue.reactive({value:[]}) can be avoided by making the whole store reactive
  • data() is a local copy, but you really want a single source of the truth (i.e the store), so access it via a computed property (basically the way Vuex works).
var self = currentClassInstance // this

self.store = Vue.reactive({
  resources: [],
  setResources(resources) {
    this.resources = resources
  }, 
})

const app_draw = {

  computed: {
    resources() {
      return self.store.resources
    }
  }
       
  template: '<div v-for="(resource, key) in resources" :data-key="key">{{resource.name}}</div>'
};

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.