Im Folgenden werde ich einen Artikel mit Ihnen teilen, um das Problem zu lösen, dass Vue Änderungen in Arrays oder Objekten nicht erkennen kann. Er hat einen guten Referenzwert und ich hoffe, dass er für alle hilfreich ist.
Sehen wir uns ein Beispiel an:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>vue</title> <script src="https://unpkg.com/vue@2.3.3/dist/vue.js"></script> <style> li:hover { cursor: pointer; } </style> </head> <body> <p class="wrap"> <ul> <li v-for="item,index in items" v-on:click="handle(index)"> <span>{{item.name}}</span> <span>{{numbers[index]}}</span> </li> </ul> </p> <script> var vm = new Vue({ el: ".wrap", data: { numbers: [], items: [ {name: 'jjj'}, {name: 'kkk'}, {name: 'lll'}, ] }, methods: { handle: function (index) { // WHY: 更新数据,view层未渲染,但通过console这个数组可以发现数据确实更新了 if (typeof(this.numbers[index]) === "undefined" ) { // 注:下面这么设置是可以的。例如 // var arr = []; // arr[3]=3; // console.log(arr) //[empty × 3, 3] this.numbers[index] = 1; // this.numbers.splice(index,0,1) //用splice方法能同步显示,但得不到想要的效果 } else { this.numbers[index]++; // this.numbers.splice(index,1,this.numbers[index]++) } // console.log(this.numbers) } } }); </script> </body> </html>
Der Effekt, den Sie erzielen möchten, besteht darin, auf li zu klicken, um zu sehen, ob vm.nymbers[index] existiert, es gibt keine Einstellung ist 1, plus 1, falls vorhanden.
Nach dem Klicken wurde die Nummer in der Ansichtsebene nicht aktualisiert. Beim Drucken auf der Konsole wurde jedoch festgestellt, dass die Daten aktualisiert wurden, die Ansichtsebene sie jedoch nicht rechtzeitig erkannte.
Sehen Sie sich eine weitere Änderung an:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>vue</title> <script src="https://unpkg.com/vue@2.3.3/dist/vue.js"></script> <style> li:hover { cursor: pointer; } </style> </head> <body> <p class="wrap"> <ul> <li v-for="item,index in items" v-on:click="handle(index)"> <span>{{item.name}}</span> <!--<span>{{numbers[index]}}</span>--> </li> </ul> </p> <script> var vm = new Vue({ el: ".wrap", data: { // numbers: [], items: [ {name: 'jjj'}, {name: 'kkk'}, {name: 'lll'}, ] }, methods: { handle: function (index) { // 不是数组,这里更新数据就可以直接在view层渲染 this.items[index].name += " success"; // console.log(this.numbers) } } }); </script> </body> </html>
Sie können sehen, dass die Ansichtsebene hier rechtzeitig aktualisiert werden kann, aber warum kann dies nicht getan werden, wenn es darum geht das Array?
Schauen Sie sich die offizielle Dokumentation von Vue2.0 an:
Aufgrund von JavaScript-Einschränkungen kann Vue die folgenden geänderten Arrays nicht erkennen:
Wenn Sie den Index verwenden, um ein Element direkt festzulegen, zum Beispiel: vm.items[indexOfItem] = newValue
Wenn Sie die Länge des Arrays ändern, zum Beispiel: vm.items.length = newLength
Um die erste Art von Problem zu lösen, können die folgenden beiden Methoden den gleichen Effekt wie vm.items[indexOfItem] = newValue erzielen und auch Statusaktualisierungen auslösen:
// Vue.set Vue.set(example1.items, indexOfItem, newValue)
// Array.prototype.splice example1.items.splice(indexOfItem, 1, newValue)
Sie kann auch die Instanzmethode vm.$ set verwenden, die nur ein Alias für das globale Vue.set ist.
Oder aufgrund von JavaScript-Einschränkungen kann Vue das Hinzufügen oder Löschen von Objekteigenschaften nicht erkennen:
var vm = new Vue({ data: { a: 1 } }) // `vm.a` 现在是响应式的 vm.b = 2 // `vm.b` 不是响应式的
Für bereits erstellte Instanzen kann Vue keine dynamisch reagierenden Eigenschaften auf Stammebene hinzufügen. Sie können jedoch reaktive Eigenschaften zu verschachtelten Objekten hinzufügen, indem Sie die Methode Vue.set(object, key, value) verwenden. Zum Beispiel für:
var vm = new Vue({ data: { userProfile: { name: 'Anika' } } })
Manchmal müssen Sie einem vorhandenen Objekt möglicherweise mehrere neue Eigenschaften zuweisen, z. B. mithilfe von Object.assign() oder _.extend(). In diesem Fall sollten Sie ein neues Objekt mit den Eigenschaften beider Objekte erstellen. Wenn Sie also ein neues reaktives Attribut hinzufügen möchten, sollten Sie Folgendes tun, anstatt wie folgt auszusehen:
Object.assign(this.userProfile, { age: 27, favoriteColor: 'Vue Green' })
:
this.userProfile = Object.assign({}, this.userProfile, { age: 27, favoriteColor: 'Vue Green' })
Daher das oben Gesagte Beispiel sollte geändert werden in:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>vue</title> <script src="https://unpkg.com/vue@2.3.3/dist/vue.js"></script> <style> li:hover { cursor: pointer; } </style> </head> <body> <p class="wrap"> <ul> <li v-for="item,index in items" v-on:click="handle(index)"> <span>{{item.name}}</span> <span>{{numbers[index]}}</span> </li> </ul> </p> <script> var vm = new Vue({ el: ".wrap", data: { numbers: [], items: [ {name: 'jjj'}, {name: 'kkk'}, {name: 'lll'}, ] }, methods: { handle: function (index) { if (typeof(this.numbers[index]) === "undefined" ) { this.$set(this.numbers, index, 1); //(arr,index,newvalue) } else { this.$set(this.numbers, index, ++this.numbers[index]); } } } }); </script> </body> </html>
Fertig!
1.17 Ergänzung---------------------------------
Wie ist zu verstehen, dass „Vue nicht dynamisch reaktionsfähige Eigenschaften auf Stammebene zu bereits erstellten Instanzen hinzufügen kann“?
Zum Beispiel:
var vm=new Vue({ el:'#test', data:{ //data中已经存在info根属性 info:{ name:'小明' } } }); //给info添加一个性别属性 Vue.set(vm.info,'sex','男');
Das Obige ist der richtige Ansatz, aber es wird ein Fehler gemeldet, wenn Sie Folgendes tun:
Vue.set(vm.data,'sex','男')
Eigentlich können Sie Attribute nicht direkt zu Daten hinzufügen, aber Sie können Attribute zu Objekten in Daten hinzufügen.
Eigentlich ist vm.data undefiniert.
Ich habe das Obige für Sie zusammengestellt und hoffe, dass es Ihnen in Zukunft hilfreich sein wird.
Verwandte Artikel:
Vue implementiert die aktive Klickwechselmethode
Das obige ist der detaillierte Inhalt vonWie kann das Problem gelöst werden, dass Vue Änderungen in Arrays oder Objekten nicht erkennen kann?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!