web-dev-qa-db-fra.com

Vuejs récupère son ancienne valeur lors d'un événement change

S'il vous plaît se référer à mon extrait ci-dessous. Comment puis-je obtenir l'ancienne valeur du modèle modifié, dans ce cas, l'âge est en vue?

var app = new Vue({
  el:"#table1",
  data:{
   items:[{name:'long name One',age:21},{name:'long name Two',age:22}]
  },
  methods:{
    changeAge:function(item,event){
      alert(item.age);
    }
  }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://unpkg.com/vue/dist/vue.js"></script>

<table class="table table-cart" id="table1">
   <thead>
     <tr>
       <th>Name</th>
       <th>Age</th>
     </tr>
  </thead>
   <tbody>
     <tr v-for="(item,index) in items">
       <td>{{item.name}} :</td>       
       <td>
         <input type="text" name="qty"
                v-model="item.age"   
                @change="changeAge(item,$event)">
       </td>
     </tr>
   </tbody>
 </table>

J'essaie d'utiliser la montre, mais je ne parviens pas à vous aider à surveiller l'âge et la variété des objets 

9
madi

Vous n'obtenez pas l'ancienne valeur de l'élément on-change comme expliqué ici . De même, lorsque vous regardez un objet, vous ne pouvez pas obtenir une valeur plus ancienne comme expliqué ici jusqu'à ce que la référence de l’objet change. 

Pour contourner ces problèmes, vous pouvez créer une propriété calculée qui sera un clone de vos données items. Vous pouvez également placer un observateur sur cette propriété calculée pour mieux connaître l'ancienne valeur.

var app = new Vue({
  el:"#table1",
  data:{
   items:[{name:'long name One',age:21},{name:'long name Two',age:22}]
  },
  watch:{
    clonedItems: function(newVal, oldVal){
      alert(JSON.stringify(newVal));
      alert(JSON.stringify(oldVal));
    }
  },
  computed:{
    clonedItems: function(){
       return JSON.parse(JSON.stringify(this.items))
    }
  }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://unpkg.com/vue/dist/vue.js"></script>

<table class="table table-cart" id="table1">
   <thead>
     <tr>
       <th>Name</th>
       <th>Age</th>
     </tr>
  </thead>
   <tbody>
     <tr v-for="(item,index) in items">
       <td>{{item.name}} :</td>       
       <td>
         <input type="text" name="qty"
                v-model="item.age">
       </td>
     </tr>
   </tbody>
 </table>

7
Saurabh

Cette solution suppose que vous avez besoin de l'ancienne valeur uniquement lorsque vous gérez le changement provenant d'une entrée utilisateur, et non d'un changement de modèle générique, ce qui est probablement le cas. J'ai ajouté ci-dessous un schéma de solution surveillant tous les changements, si nécessaire, mais il est peut-être préférable de contrôler les autres changements aux endroits où ils se produisent, et non dans cette composante. 

Supprimez v-model et remplacez-le par une manipulation manuelle.

Il est important de noter que "bien que quelque peu magique, v-model est essentiellement un sucre de syntaxe pour la mise à jour des données sur les événements saisis par l'utilisateur (...)" . Donc, sans trop de mal, vous pouvez le supprimer et gérer les événements directement, comme vous le faites déjà presque.

Commencez par remplacer v-model par :value. L'entrée suivra toujours les mises à jour item.age, mais ne mettra pas à jour l'âge automatiquement. 

<input type="text" name="qty"
       :value="item.age"
       @change="changeAge(item,$event)">

Ensuite, pour mettre à jour la valeur, ajoutez item.age = event.target.value à changeAge, comme ceci:

changeAge: function(item, event){
  alert(item.age);  // Old value
  alert(event.target.value);  // New value
  item.age = event.target.value;  // Actual assignment
}

Remarque: vous voudrez peut-être utiliser @input, c'est ce que v-model utilise réellement.

Et ça y est, ça devrait faire l'affaire. Si vous devez empêcher le changement, vous pouvez simplement omettre l’affectation. Cependant, vous devez réinitialiser la valeur saisie. item.age = item.age of Vue.set(item, 'age', item.age) peut faire l'affaire, mais je ne suis pas tout à fait sûr que ce sera le cas.

Remarque: event.target.value, si vous avez besoin d’un nombre, utilisez parseInt().

Créez une occurrence de composant distincte pour chaque élément et créez-y une montre

Au cas où vous auriez besoin de surveiller tous les changements. Cependant, si vous en avez besoin, vous devriez peut-être le faire ailleurs, pas dans cet élément.

Je n'ai pas tous les détails en main, je vais donc me contenter du brouillon général: dans votre v-for, au lieu de <input>, vous placez un autre composant, par exemple <my-item>. Vous mettez v-model=item dessus. À l'intérieur du composant, vous créez le <input> et lui transmettez le paramètre value, ainsi que les événements input/change à l'extérieur. Dans votre composant, un seul élément contient un accessoire, vous pouvez donc y attacher un observateur directement. Documents pertinents: Notions de base sur les composants , Personnalisation du composant v-model , Accessoires .

2
Frax

C'est peut-être trop tard. Cela a fonctionné pour moi tant que le nom de la fonction à l'intérieur de l'objet de surveillance est nommé en tant que variable surveillée. Il ne surveille que la variable spécifique.

 watch:{
items: function(newVal, oldVal){
  console.log("New value: "+ newVal + ", Old value: " + oldVal);
},
other_variable: function(newVal, oldVal){
  console.log("New value: "+ newVal + ", Old value: " + oldVal);
},

}

1
G...... T......

remplacez v-model avec valeur prop v-model est une liaison bidirectionnelle, il rendra votre état complexe puis modifiera manuellement la propriété age dans l'événement change 

<input type="text" name="qty"
                :value="item.age"   
                @change="changeAge">



export default {
  change(val) {
     let ov = this.item.age
     let nv = val
     // do something
     // this.item.age = nv
   }
}
0
lynnic

Vous pouvez simplement utiliser 

<input type="text" name="qty" v-model="item.age" @change="changeAge($event)">

et

changeAge: function(event){
  item = event.target.value;  // Actual assignment
}

objet de méthode en vue

0
Rahul Reghunath