Vue.js, lista v-for che non si aggiorna. Ecco la soluzione
Vue.js, lista v-for che non si aggiorna. Ecco la soluzione
Risolvere una lista v-for che non si aggiorna
Come risolvere l’enigma di una lista v-for che non si aggiorna?
A volte può capitare, magari dopo aver creato un progetto con la CLI del Vue come nel mio caso, di aggiornare una lista e non vedere nessun cambiamento nel DOM della pagina.
Questo a volte può essere davvero frustrante.
Negli esempi di seguito userò esempi di file .vue ma vale la stessa cosa anche per i classici .html/.js (che ovviamente avranno una base leggermente differente, per esempio per quanto riguarda i data che nei file .vue vengono restituiti da un metodo mentre nella forma classica fanno parte di un oggetto, non c’è l’export default..)
Mettiamo di avere una situazione del genere (nome_modulo.vue):
<template> <div id="app"> <p v-for="(prop, index) in lista_proprieta" @click='cambia_proprieta(index)' v-bind:key='index'>{{ prop }}</p> </div> </template> <script> import Vue from 'vue' export default { name: 'app', data: function () { return { lista_proprieta: [ "Dire", "Fare", "Baciare" ] }; }, computed: { }, methods: { cambia_proprieta: function (indice) { this.lista_proprieta[indice] = "Proprietà cambiata"; } } } </script>
In teoria, al click su un elemento della lista, dovremmo vedere un cambiamento nel testo dell’elemento in “Proprietà cambiata”.
Di solito questo approccio funziona senza problemi ma questa volta no.. che fare?
La soluzione
La soluzione sta nell’usare la seguente funzione del Vue: Vue.set(Array, key, Valore);
In questo modo il Vue si assicurerà che la lista verrà aggiornata nel DOM.
Per usare questa funzione però dobbiamo prima fare due cose semplicissime:
- Includere questa linea all inizio dello script: import Vue from ‘vue’;
- Settare l’attributo key negli elementi del v-for: v-bind:key=”index”
Ecco dunque l’esempio di prima, funzionante in ogni caso (nome_modulo.vue):
<template> <div id="app"> <p v-for="(prop, index) in lista_proprieta" @click='cambia_proprieta(index)' v-bind:key='index'>{{ prop }}</p> </div> </template> <script> import Vue from 'vue' export default { name: 'app', data: function () { return { lista_proprieta: [ "Dire", "Fare", "Baciare" ] }; }, computed: { }, methods: { cambia_proprieta: function (indice) { Vue.set(this.lista_proprieta, indice, "Proprietà cambiata"); } } } </script>
Liste di oggetti
Qualcuno di voi potrebbe chiedersi: “E nel caso dovessi manipolare una lista di oggetti?”. In quel caso l’approccio classico funziona sempre alla grande, ecco comunque un semplice esempio (sempre nome_modulo.vue):
<template> <div id="app"> <p v-for="(prop, index) in lista_proprieta" @click='cambia_proprieta(index)' v-bind:key='index'>{{ prop.nome }} {{ prop.cognome }}</p> </div> </template> <script> import Vue from 'vue' export default { name: 'app', data: function () { return { lista_proprieta: [ {nome: "Italo", cognome: "Balbo"}, {nome: "Carlo", cognome: "Seganti"}, {nome: "Teresio", cognome: "Martinoli"} ] }; }, computed: { }, methods: { cambia_proprieta: function (indice) { this.lista_proprieta[indice].nome = "Asso"; } } } </script>
Spero vi sarà utile, alla prossima!