Heim > Web-Frontend > js-Tutorial > Wie kann das Problem gelöst werden, dass Vue Änderungen in Arrays oder Objekten nicht erkennen kann?

Wie kann das Problem gelöst werden, dass Vue Änderungen in Arrays oder Objekten nicht erkennen kann?

亚连
Freigeben: 2018-06-04 16:32:15
Original
2217 Leute haben es durchsucht

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: &#39;jjj&#39;},
   {name: &#39;kkk&#39;},
   {name: &#39;lll&#39;},
  ]
  },
  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>
Nach dem Login kopieren

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: &#39;jjj&#39;},
   {name: &#39;kkk&#39;},
   {name: &#39;lll&#39;},
  ]
  },
  methods: {
  handle: function (index) {
   // 不是数组,这里更新数据就可以直接在view层渲染
   this.items[index].name += " success";
  // console.log(this.numbers)
  }
  }
 });
 </script>
</body>
</html>
Nach dem Login kopieren

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)
Nach dem Login kopieren
// Array.prototype.splice 
example1.items.splice(indexOfItem, 1, newValue)
Nach dem Login kopieren

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` 不是响应式的
Nach dem Login kopieren

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: &#39;Anika&#39; 
 } 
 } 
})
Nach dem Login kopieren

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: &#39;Vue Green&#39; 
})
Nach dem Login kopieren

:

this.userProfile = Object.assign({}, this.userProfile, { 
 age: 27, 
 favoriteColor: &#39;Vue Green&#39; 
})
Nach dem Login kopieren

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: &#39;jjj&#39;},
   {name: &#39;kkk&#39;},
   {name: &#39;lll&#39;},
  ]
  },
  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>
Nach dem Login kopieren

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:&#39;#test&#39;, 
 data:{ 
  //data中已经存在info根属性 
  info:{ 
   name:&#39;小明&#39; 
  } 
 } 
}); 
//给info添加一个性别属性 
Vue.set(vm.info,&#39;sex&#39;,&#39;男&#39;);
Nach dem Login kopieren

Das Obige ist der richtige Ansatz, aber es wird ein Fehler gemeldet, wenn Sie Folgendes tun:

Vue.set(vm.data,&#39;sex&#39;,&#39;男&#39;)
Nach dem Login kopieren

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:

Grundsätze und Implementierungsmethoden für die gemeinsame Nutzung von Ressourcen für den übergeordneten und untergeordneten Prozess von NodeJS

Vue-Mobiltelefonnummer, regelmäßige Überprüfung per E-Mail Und ein Beispiel für das Senden eines Bestätigungscodes in den 60er Jahren

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!

Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage