Tengo un elemento vue.js en mi página que rastrea los cambios realizados en un formulario. Se parece a esto:

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

Cuando se detecta un cambio, el cambio se inserta en la matriz changes_applied, y se muestra en el div "Cambios aplicados" como se esperaba. Las eliminaciones también funcionan, lo que simplemente llama al método remove en el objeto vue.

También tengo un botón "borrar" que no está conectado a la instancia de vue, y cuando se hace clic, establece la fuente de datos en una matriz vacía usando changes_applied = [];

El problema es que después de que esto se borra usando el botón, los cambios / adiciones a la matriz de cambios ya no se muestran en el elemento vue, es como si el elemento vue ya no estuviera adjunto a la matriz changes_applied.

¿Me estoy perdiendo un enlace o algo aquí que tiene que suceder, o hay una "forma vue" de borrar los datos vue sin tocar la matriz fuente real?

1
user101289 28 feb. 2018 a las 21:53

3 respuestas

La mejor respuesta

Mark_M ya proporcionó una buena explicación, agregaré una demostración, ya que creo que es más fácil entender cómo funciona.

Puede copiar el valor de la matriz a los datos, pero luego todas las operaciones deben realizarse directamente en los datos:

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 feb. 2018 a las 19:31

Su matriz de elementos se inicializa con change_applied pero no mantiene enlaces, es solo el valor predeterminado para los elementos cuando se crea la instancia. Entonces, si cambia los cambios_aplicados, esto no afectará la matriz de elementos en la instancia de vue.

Ejemplo

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 feb. 2018 a las 19:25

No deberías cambiar la matriz changes_applied; Vue realmente no está reaccionando a los cambios en esa matriz. Solo tipo de funciona cuando this.items apunta a la misma referencia de matriz. Cuando cambia esa referencia al reasignar changes_applied se rompe porque está manipulando changes_applied pero ya no es la misma matriz que this.items.

En su lugar, deberías manipular this.items directamente:

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

Para borrarlo, puede configurar:

 this.items = []

Y funcionará como se esperaba.

1
Mark Meyer 28 feb. 2018 a las 19:09