Данные vue.js не обновляются после очистки

У меня есть элемент vue.js на моей странице, который отслеживает изменения, внесенные в форму. Это выглядит так:

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);
        }
    }
});

Когда изменение обнаруживается, оно помещается в массив changes_applied и, как и ожидалось, отображается в div «Примененные изменения». Также работают удаления, которые просто вызывают метод remove для объекта vue.

У меня также есть кнопка «очистить», которая не связана с экземпляром vue, и при ее нажатии она устанавливает источник данных обратно в пустой массив, используя changes_applied = [];

Проблема в том, что после того, как это очищено с помощью кнопки, изменения / дополнения к массиву изменений больше не отображаются в элементе vue - это похоже на то, что элемент vue больше не прикреплен к массиву changes_applied.

Мне не хватает привязки или чего-то здесь, что должно произойти, или есть «способ vue», чтобы очистить данные vue, не касаясь фактического исходного массива?


person user101289    schedule 28.02.2018    source источник


Ответы (3)


Mark_M уже дал хорошее объяснение, я добавлю демо, так как думаю, что легче понять, как это работает.

Вы можете скопировать значение массива в данные, но тогда все операции должны выполняться непосредственно с данными:

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>

person a--m    schedule 28.02.2018

Вы не должны изменять массив changes_applied; Vue на самом деле не реагирует на изменения в этом массиве. Он работает только вроде, когда this.items указывает на ту же ссылку на массив. Когда вы изменяете эту ссылку путем переназначения changes_applied, она прерывается, потому что вы затем манипулируете changes_applied, но это уже не тот же массив, что и this.items.

Вместо этого вы должны напрямую манипулировать this.items:

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

Чтобы очистить его, вы можете установить:

 this.items = []

и он будет работать как положено.

person Mark    schedule 28.02.2018

Ваш массив элементов инициализируется с помощью changes_applied, но не связывает привязки, это просто значение по умолчанию для элементов при создании экземпляра. Поэтому, если вы измените changes_applied, это не повлияет на массив элементов в экземпляре vue.

пример

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>

person DobleL    schedule 28.02.2018