106 votes

Vuejs et Vue.set(), mettre à jour un tableau

Je suis nouveau dans Vuejs. J'ai fait quelque chose, mais je ne sais pas si c'est la bonne solution.

ce que je veux

Je veux mettre des dates dans un tableau et les mettre à jour lors d'un événement. J'ai d'abord essayé Vue.set, mais cela n'a pas fonctionné. Maintenant, après avoir changé l'élément de mon tableau :

this.items[index] = val;
this.items.push();

Je n'ajoute rien au tableau par push() et il se met à jour. Mais parfois le dernier élément est caché, d'une manière ou d'une autre... Je pense que cette solution est un peu bancale, comment la rendre stable ?

Le code simple est ici :

new Vue({
  el: '#app',
  data: {
    f: 'DD-MM-YYYY',
    items: [
      "10-03-2017",
      "12-03-2017"
    ]
  },
  methods: {

    cha: function(index, item, what, count) {
        console.log(item + " index > " + index);
      val = moment(this.items[index], this.f).add(count, what).format(this.f);
        this.items[index] = val;
      this.items.push();
      console.log("arr length:  " + this.items.length);
    }
  }
})

ul {
  list-style-type: none;
}

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/1.0.11/vue.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.10.6/moment.min.js"></script>
<div id="app">
  <ul>
    <li v-for="(index, item) in items">
    <br><br>
      <button v-on:click="cha(index, item, 'day', -1)">
      - day</button>
      {{ item }}
      <button v-on:click="cha(index, item, 'day', 1)">
      + day</button>
    <br><br>
    </li>
  </ul>
</div>

130voto

Martin Calvert Points 916

EDIT 2

  • Pour tous les changements d'objets qui nécessitent de la réactivité Vue.set(object, prop, value)
  • Pour les mutations de tableaux, vous pouvez consulter la liste des mutations actuellement prises en charge aquí

EDIT 1

Pour vuex, vous devrez faire Vue.set(state.object, key, value)


Original

Je m'adresse donc aux autres personnes qui se posent cette question. Il semble qu'à un moment donné, dans Vue 2.*, ils ont supprimé la fonction this.items.$set(index, val) en faveur de this.$set(this.items, index, val) .

Splice est toujours disponible et voici un lien vers les méthodes de mutation de tableaux disponibles dans vue lien .

0 votes

Quelle chaîne de caractères dois-je fournir comme "index" ?

0 votes

@Kokodoko pouvez-vous préciser ce que vous essayez de faire ? Si c'est un tableau, il devrait y avoir un nombre pour l'index. Une chaîne de caractères le serait si vous définissiez un champ sur un objet.

0 votes

Ah ok, mon IDE a insisté pour que ce soit une chaîne de caractères, ça doit être un bug.

60voto

Borjante Points 2598

VueJS ne peut pas récupérer vos modifications de l'état si vous manipulez des tableaux de cette manière.

Comme expliqué dans l'affaire Les erreurs courantes des débutants vous devez utiliser des méthodes de tableau comme push, splice ou autre et ne jamais modifier les index comme ceci a[2] = 2 ni la propriété .length d'un tableau.

new Vue({
  el: '#app',
  data: {
    f: 'DD-MM-YYYY',
    items: [
      "10-03-2017",
      "12-03-2017"
    ]
  },
  methods: {

    cha: function(index, item, what, count) {
      console.log(item + " index > " + index);
      val = moment(this.items[index], this.f).add(count, what).format(this.f);

      this.items.$set(index, val)
      console.log("arr length:  " + this.items.length);
    }
  }
})

ul {
  list-style-type: none;
}

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/1.0.11/vue.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.10.6/moment.min.js"></script>
<div id="app">
  <ul>
    <li v-for="(index, item) in items">
      <br><br>
      <button v-on:click="cha(index, item, 'day', -1)">
      - day</button> {{ item }}
      <button v-on:click="cha(index, item, 'day', 1)">
      + day</button>
      <br><br>
    </li>
  </ul>
</div>

1 votes

Comme indiqué dans la documentation, $set est juste un joli .splice(). Cela a du sens car comme il est dit dans la documentation, vous devez modifier le tableau en utilisant ses méthodes.

1 votes

Ne combinez pas les tabulations avec les espaces, la taille d'une tabulation est apparemment différente sur l'application SE, ce qui rend difficile la lecture de votre code.

0 votes

Dans mon cas, le spread-operator ES6 pour l'opération push ne fonctionne pas correctement avec vue.

19voto

Mykola Korol Points 401

Comme indiqué précédemment, VueJS ne peut tout simplement pas suivre ces opérations (assignation d'éléments de tableau). Toutes les opérations qui sont suivies par VueJS avec un tableau sont aquí . Mais je vais les recopier une fois de plus :

  • pousser()
  • pop()
  • shift()
  • unshift()
  • splice()
  • tri()
  • inverser()

Au cours du développement, vous êtes confronté à un problème - comment vivre avec cela :).

push(), pop(), shift(), unshift(), sort() et reverse() sont assez simples et vous aident dans certains cas, mais l'essentiel se trouve dans la fonction splice() qui vous permet de modifier efficacement le tableau qui sera suivi par VueJs. Je peux donc partager certaines des approches les plus utilisées pour travailler avec des tableaux.

Vous devez remplacer Item dans Array :

// note - findIndex might be replaced with some(), filter(), forEach() 
// or any other function/approach if you need 
// additional browser support, or you might use a polyfill
const index = this.values.findIndex(item => {
          return (replacementItem.id === item.id)
        })
this.values.splice(index, 1, replacementItem)

Remarque : si vous souhaitez simplement modifier un champ d'un élément, vous pouvez le faire en cliquant sur le bouton "Modifier" :

this.values[index].itemField = newItemFieldValue

Et ceci sera suivi par VueJS comme le sont les champs item(Object).

Vous devez vider le tableau :

this.values.splice(0, this.values.length)

En fait, vous pouvez faire beaucoup plus avec cette fonction splice() - lien w3schools Vous pouvez ajouter plusieurs enregistrements, en supprimer plusieurs, etc.

Vue.set() et Vue.delete()

Vue.set() et Vue.delete() peuvent être utilisés pour ajouter des champs à votre version de données de l'interface utilisateur. Par exemple, vous avez besoin de données calculées supplémentaires ou de drapeaux dans vos objets. Vous pouvez le faire pour vos objets, ou pour une liste d'objets (dans la boucle) :

 Vue.set(plan, 'editEnabled', true) //(or this.$set)

Et renvoyer les données éditées au back-end dans le même format que celui utilisé avant l'appel Axios :

 Vue.delete(plan, 'editEnabled') //(or this.$delete)

0voto

Geole Points 258

Une alternative - et une approche plus légère de votre problème - pourrait être d'éditer temporairement le tableau et d'assigner à nouveau le tableau entier à votre variable. En effet, Vue ne surveille pas les éléments individuels, il surveille la mise à jour de l'ensemble de la variable.

Cela devrait donc fonctionner également :

var tempArray[];

tempArray = this.items;

tempArray[targetPosition]  = value;

this.items = tempArray;

Ceci devrait également mettre à jour votre DOM.

-3voto

Observez ici la réactivité des objets et des tableaux :

https://vuejs.org/v2/guide/reactivity.html

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X