web-dev-qa-db-de.com

Vuejs erhalten bei einem Änderungsereignis einen alten Wert

Bitte verweisen Sie auf meinen Ausschnitt unten. Wie kann ich den alten Wert des geänderten Modells erhalten, in diesem Fall ist das Alter in vuejs?

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>

Ich versuche, watch zu verwenden, aber ich kann keine Hilfe finden, wenn ich eine Reihe von Gegenständen im Alter beobachte. 

9
madi

Sie erhalten nicht den alten Wert des Elements bei Änderung, wie hier . Auch beim Betrachten eines Objekts können Sie keinen älteren Wert erhalten, wie hier beschrieben, bis sich die Referenz des Objekts ändert. 

Um dies zu umgehen, können Sie eine berechnete Eigenschaft erstellen, die aus Ihren items-Daten kopiert wird, und Sie können einen Beobachter über diese berechnete Eigenschaft setzen, um auch den alten Wert kennen zu lernen. Siehe untenstehenden Arbeitscode:

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

Bei dieser Lösung wird davon ausgegangen, dass Sie den alten Wert nur für die Bearbeitung der durch Benutzereingaben hervorgerufenen Änderung benötigen und nicht für einen generischen Modellwechsel - was wahrscheinlich der Fall ist. Im Folgenden habe ich eine Lösungsskizze hinzugefügt, um alle Änderungen zu überprüfen, falls nötig, obwohl es vielleicht besser ist, die anderen Änderungen an den Stellen zu kontrollieren, an denen sie auftreten, und nicht in dieser Komponente. 

v-model ablegen und durch manuelle Handhabung ersetzen.

Es ist wichtig anzumerken, dass "obwohl es ein bisschen magisch ist, ist v-model im Wesentlichen ein Syntaxzucker für die Aktualisierung von Daten zu Benutzereingabeereignissen (...)" . Ohne großen Schaden können Sie ihn also entfernen und die Ereignisse direkt abwickeln, wie Sie es fast schon tun.

Ersetzen Sie zuerst v-model durch :value. Die Eingabe folgt weiterhin den item.age-Aktualisierungen, aber das Alter wird nicht automatisch aktualisiert. 

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

Um den Wert tatsächlich zu aktualisieren, fügen Sie item.age = event.target.value wie folgt zu changeAge hinzu:

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

Hinweis: Möglicherweise möchten Sie stattdessen @input verwenden. Dies ist, was v-model tatsächlich verwendet.

Und das ist es, es sollte den Trick tun. Wenn Sie die Änderung verhindern möchten, können Sie die Zuordnung einfach weglassen. Sie müssen jedoch den Eingangswert zurücksetzen. item.age = item.age von Vue.set(item, 'age', item.age) mag den Trick tun, aber ich bin nicht ganz sicher, ob das der Fall ist.

Hinweis: event.target.value, wenn Sie eine Nummer benötigen, verwenden Sie parseInt().

Erstellen Sie für jeden Artikel eine separate Komponenteninstanz und erstellen Sie dort eine Uhr

Falls Sie alle Änderungen beobachten müssen. Wenn Sie das jedoch benötigen, sollten Sie dies vielleicht an einem anderen Ort tun, nicht an dieser Komponente.

Ich habe nicht alle Details bereit, also werde ich nur den allgemeinen Entwurf vorlegen: In Ihrem v-for statt einfachen <input> setzen Sie eine andere Komponente ein, sagen Sie <my-item>. Sie setzen v-model=item darauf. Innerhalb der Komponente erstellen Sie den <input> und leiten die value-Eigenschaft an sie weiter. Außerdem leiten Sie die input/change-Ereignisse nach außen weiter. In Ihrer Komponente ist ein einzelner Gegenstand eine einzelne Requisite, sodass Sie einen Beobachter direkt daran anhängen können. Relevante Dokumente: Komponentengrundlagen , Customizing-Komponente v-model , Requisiten .

2
Frax

Es kann zu spät sein. Dies funktionierte für mich, solange der Funktionsname innerhalb des Überwachungsobjekts als die überwachte Variable bezeichnet wird. Es überwacht nur die spezifische Variable.

 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......

ersetzen Sie v-model mit value prop v-model ist eine bidirektionale Bindung. Dadurch wird Ihr Status komplex Anschließend wird die age -Eigenschaft im Änderungsereignis manuell geändert 

<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

Sie können einfach verwenden 

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

und

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

in vue method object

0
Rahul Reghunath