user101289
user101289

Reputation: 10422

vue.js data not updated after clear

I have a vue.js item in my page that tracks changes made to a form. It looks like this:

var changes_applied = [];

var changes_applied_block = new Vue({
    name: "ChangesApplied",
    el: '#changes-applied',
    data: {
        items: changes_applied
    },
    methods: {
        remove: function(index) {
            changes_applied.splice(index, 1);
        }
    }
});

When a change is detected the change is pushed onto the changes_applied array, and it shows up in the "Changes Applied" div as expected. The deletes also work, which just calls the remove method on the vue object.

I also have a "clear" button that's not connected to the vue instance, and when it's clicked it sets the data source back to an empty array using changes_applied = [];

The problem is that after this is cleared using the button, the changes / additions to the changes array no longer show up in the vue element-- it's like the vue element is no longer attached to the changes_applied array.

Am I missing a binding or something here that needs to happen, or is there a "vue way" to clear the vue data without touching the actual source array?

Upvotes: 1

Views: 2527

Answers (3)

a--m
a--m

Reputation: 4782

Mark_M already provided a good explanation, I'll add a demo, since I think its easier to understand how it works.

You can copy the value of the array to data, but then all operations must be done to the data directly:

const changes_applied = [
  {id: 1},
  {id: 2},
  {id: 3}
];

const vm = new Vue({
  el: '#app',
  data: {items: changes_applied},
  methods: {
    add() {
      const id = this.items.length + 1
      this.items.push({id})
    },
    remove() {
      this.items.pop()
    },
    clear() {
      this.items = []
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.13/vue.js"></script>

<div id="app">
  <div>
    <button type="button" @click="add">Add</button>
    <button type="button" @click="remove">Remove</button>
    <button type="button" @click="clear">Clear</button>
  </div>
  <ul name="list">
    <li v-for="item in items" :key="item.id">
      Item {{ item.id }}
    </li>
  </ul>
</div>

Upvotes: 1

DobleL
DobleL

Reputation: 3918

Your items array is initialized with changes_applied but does not mantaing bindings, it's just the default value for items when the instance is created. So if you change the changes_applied this will not affect the items array on vue instance.

example

new Vue({
  el: '#app',
  data: function () {
    return {
      items: myArr,
      newItem: ''
    }
  },
  methods: {
    addItem () {
      this.items.push(this.newItem)
      this.newItem = ''
    },
    remove (index) {
      this.items.splice(index, 1)
    },
    clear () {
      this.items = []
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.13/vue.js"></script>
<div id="app">
  <input type="text" v-model="newItem" /> 
  <button @click="addItem">Add</button> 
  <button @click="clear">Clear</button>
  <p v-for="(item, index) in items" @click="remove(index)">{{item}}</p>
</div>
<!-- from outside vue instance-->
<button onClick="clearFromOutside()">clear from outside</button>
<script>
var myArr = ['hola', 'mundo'];
  function clearFromOutside() {
    console.log(myArr)
    myArr = [];
    console.log(myArr)
  }
</script>

Upvotes: 2

Mark
Mark

Reputation: 92440

You shouldn't be changing the changes_applied array; Vue isn't really reacting to changes on that array. It only sort of works when this.items is pointed to the same array reference. When you change that reference by reassigning changes_applied it breaks because you are then manipulating changes_applied but it is not longer the same array as this.items.

You should instead be manipulating this.items directly:

methods: {
    remove: function(index) {
        this.items.splice(index, 1);
    }

To clear it you can set:

 this.items = []

and it will work as expected.

Upvotes: 2

Related Questions