简体   繁体   中英

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?

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.

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> 

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> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM