На моей странице есть элемент 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, и оно отображается в элементе «Изменения применены», как и ожидалось. Удаление также работает, который просто вызывает метод remove для объекта vue.

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

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

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

1
user101289 28 Фев 2018 в 21:53

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>
0
a--m 28 Фев 2018 в 19:31

Ваш массив items инициализируется с помощью changes_applied, но не содержит привязок, это просто значение по умолчанию для элементов при создании экземпляра. Таким образом, если вы измените change_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>
1
DobleL 28 Фев 2018 в 19:25

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

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

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

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

 this.items = []

И это будет работать, как ожидалось.

1
Mark Meyer 28 Фев 2018 в 19:09