Maison > interface Web > js tutoriel > Comment résoudre le problème selon lequel Vue ne peut pas détecter les changements dans les tableaux ou les objets ?

Comment résoudre le problème selon lequel Vue ne peut pas détecter les changements dans les tableaux ou les objets ?

亚连
Libérer: 2018-06-04 16:32:15
original
2217 Les gens l'ont consulté

Ci-dessous, je partagerai avec vous un article qui résout le problème de l'incapacité de Vue à détecter les changements dans les tableaux ou les objets. Il a une bonne valeur de référence et j'espère qu'il sera utile à tout le monde.

Regardons un exemple :

<!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>
Copier après la connexion

L'effet que vous souhaitez obtenir est de cliquer sur li pour voir si vm.nymbers[ index] existe, non Mis à 1 s'il est présent, plus 1 s'il est présent.

Après avoir cliqué, le numéro n'a pas été mis à jour dans la couche de vue. Cependant, grâce à l'impression de la console, il a été constaté que les données étaient mises à jour, mais la couche de vue ne l'a pas détectée à temps.

Regardez un autre changement :

<!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>
Copier après la connexion

Vous pouvez voir que la couche de vue ici peut être mise à jour à temps, mais pourquoi cela ne peut-il pas être fait alors qu'il vient au tableau ?

Regardez la documentation officielle de Vue2.0 :

En raison des limitations de JavaScript, Vue ne peut pas détecter les tableaux modifiés suivants :

Lorsque vous utilisez l'index pour définir directement un élément, par exemple : vm.items[indexOfItem] = newValue

Lorsque vous modifiez la longueur du tableau, par exemple : vm.items.length = newLength

Afin de résoudre le premier type de problème, les deux méthodes suivantes peuvent obtenir le même effet que vm.items[indexOfItem] = newValue, et déclencheront également des mises à jour de statut :

// Vue.set 
Vue.set(example1.items, indexOfItem, newValue)
Copier après la connexion
// Array.prototype.splice 
example1.items.splice(indexOfItem, 1, newValue)
Copier après la connexion

Vous pouvez également utiliser la méthode d'instance vm.$set, qui n'est qu'un alias pour le Vue.set global.

Ou en raison des limitations de JavaScript, Vue ne peut pas détecter l'ajout ou la suppression de propriétés d'objet :

var vm = new Vue({
 data: {
 a: 1
 }
})
// `vm.a` 现在是响应式的
vm.b = 2
// `vm.b` 不是响应式的
Copier après la connexion

Pour les instances déjà créées, Vue ne peut pas ajouter dynamiquement des propriétés réactives au niveau racine. Cependant, vous pouvez ajouter des propriétés réactives aux objets imbriqués à l'aide de la méthode Vue.set(object, key, value). Par exemple, pour :

var vm = new Vue({ 
 data: { 
 userProfile: { 
  name: &#39;Anika&#39; 
 } 
 } 
})
Copier après la connexion

Parfois, vous devrez peut-être attribuer plusieurs nouvelles propriétés à un objet existant, par exemple en utilisant Object.assign() ou _.extend(). Dans ce cas, vous devez créer un nouvel objet avec les propriétés des deux objets. Donc, si vous souhaitez ajouter un nouvel attribut responsive, au lieu de le faire comme ceci :

Object.assign(this.userProfile, { 
 age: 27, 
 favoriteColor: &#39;Vue Green&#39; 
})
Copier après la connexion

vous devriez faire ceci :

this.userProfile = Object.assign({}, this.userProfile, { 
 age: 27, 
 favoriteColor: &#39;Vue Green&#39; 
})
Copier après la connexion

Donc, ci-dessus L'exemple doit être remplacé par :

<!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>
Copier après la connexion

Terminé !

1.17 Supplément---------------------------------

Comment comprendre « Vue ne peut pas ajouter dynamiquement des propriétés réactives au niveau racine aux instances déjà créées » ?

Par exemple :

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;);
Copier après la connexion

Ce qui précède est l'approche correcte, mais l'approche suivante entraînera une erreur :

Vue.set(vm.data,&#39;sex&#39;,&#39;男&#39;)
Copier après la connexion

En fait, vous ne pouvez pas ajouter d'attributs directement aux données, mais vous pouvez ajouter des attributs aux objets dans les données.

En fait, vm.data n'est pas défini.

J'ai compilé ce qui précède pour vous, j'espère que cela vous sera utile à l'avenir.

Articles connexes :

Principes de partage des ressources du processus parent et du processus enfant NodeJS et méthodes de mise en œuvre

Numéro de téléphone mobile Vue, vérification régulière par e-mail Et un exemple d'envoi de code de vérification dans les années 60

Vue implémente la méthode de changement de clic actif

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal