Maison  >  Article  >  interface Web  >  Explication détaillée de la façon dont les accessoires transmettent les paramètres dans vue.js

Explication détaillée de la façon dont les accessoires transmettent les paramètres dans vue.js

亚连
亚连original
2018-06-21 14:33:402237parcourir

Je vais vous donner une analyse détaillée des connaissances pertinentes et des méthodes de résolution de problèmes des accessoires passant des paramètres dans vue.js. Les amis dans le besoin peuvent s'y référer.

Cet article utilise un exemple de démonstration pour vous donner une analyse détaillée de l'utilisation des accessoires en passant des paramètres et des solutions aux problèmes rencontrés. Ce qui suit est le contenu complet.

Il y a quelque temps, j'ai utilisé vue pour créer un système de gestion backend, dans lequel chaque page nécessite un tableau pour afficher des informations. Naturellement, j'ai pensé à extraire la table dans un composant public et à transmettre les données de différentes pages pour le rendu afin d'atteindre l'objectif de réutilisation.

Adresse de démonstration

1. Découverte du problème

Dans le composant parent, les données qui doivent être transmises au Le composant table est la table Les données de contenu tableData, la page de données de page de la table.

<p>
 <my-table :table-data="tableData" :page-info="pageInfo" id="myTable"></my-table>
</p>

Où tableData est un objet Array, qui est un tableau composé de tous les objets de données qui doivent être affichés dans le tableau. Et pageInfo est un objet Object, qui contient des informations sur la page du tableau. Initialisez les deux paires de données dans le composant parent comme suit, sous la forme de

tableData:[],
pageInfo: {
 current: 1, // 当前是第几页
 total: 100, // 数据对象的总数
 size: 20 // 每页显示的数量
}

Selon les instructions de la documentation officielle, prop est une liaison unidirectionnelle et prop ne doit pas être modifié à l'intérieur du composant enfant . La raison pour laquelle je souhaite modifier les données dans prop est principalement parce qu'une fois que prop est transmis comme valeur initiale, le sous-composant souhaite l'utiliser comme données locales. Pour cette situation, la déclaration officielle est de définir une variable locale et de l'initialiser avec la valeur de prop :

props: [&#39;tableData&#39;, &#39;pageInfo&#39;],
data() {
 return {
  tData: this.tableData,
  page: this.pageInfo
 }
}

Ensuite, selon la documentation officielle, à chaque fois que le composant parent est mis à jour, tous les accessoires du Le composant enfant sera mis à jour avec la dernière valeur. Les informations de tableData et pageInfo sont obtenues de manière asynchrone depuis le serveur via l'API :

{
 error: 0,
 msg: "调用成功.",
 data: {
  restrictioninfo: [...],
  total: 42
 }
}

Par conséquent, lorsque les données sont obtenues, le composant parent doit modifier la valeur transmise dans le composant enfant :

me.tableData = Json.data.restrictioninfo;
me.pageInfo.total = Json.data.total;

Il va de soi que la valeur du sous-composant doit être mise à jour avec la valeur renvoyée par le serveur à ce moment-là, mais le nombre total de pages du sous-composant a été mis à jour, mais les données de la table sont toujours le tableau vide lors de l'initialisation. (Point d'interrogation noir ???)


.

2. Affectation et liaison

Tout d'abord, je dois localiser où les données se sont trompées, j'ai donc fait une démo pour localiser ça.

Regardez d'abord les valeurs initiales de chaque élément dans le composant parent et le composant enfant :

Ensuite, lorsque seule la référence au tableau dans le Le composant parent est modifié, vous pouvez voir l'enfant. Le tableau d'accessoires du composant change en conséquence, mais le tableau lié dans le sous-composant ne change pas en conséquence

Par conséquent, il On peut constater que le problème réside dans cette étape

props: [&#39;tableData&#39;, &#39;pageInfo&#39;],
data() {
 return {
  tData: this.tableData,
  page: this.pageInfo
 }
}

Pour comprendre la cause première du problème, vous devez comprendre le principe de réactivité en profondeur dans le document vue.

"Dans l'option data de l'instance Vue, Vue traversera toutes les propriétés de cet objet et utilisera Object.defineProperty pour convertir toutes ces propriétés en getters/setters", " Chaque instance de composant a un objet d'instance d'observateur correspondant, qui enregistre les propriétés en tant que dépendances lors du rendu du composant. Plus tard, lorsque le setter de la dépendance est appelé, l'observateur sera invité à recalculer, ce qui entraînera la mise à jour de ses composants associés. " Le document indique La compréhension simple est que Vue lie de manière bidirectionnelle vm.$data.a dans l'option data à vm.a dans le DOM, c'est-à-dire que si l'un change, l'autre changera également. Dans le code source de Vue, il est implémenté par la fonction DefineReactive$$1 :

Mais dans la sous-section, les méthodes get et set de Object.defineProperty sont principalement utilisées pour obtenir une liaison bidirectionnelle. Dans le sous-composant, les données pros et les $data du sous-composant sont connectées de la manière suivante :

tData: this.tableData

L'interrogation du code source de Vue montre qu'il n'y a qu'une affectation entre this.tableData et tData, c'est-à-dire "=" Relation

La fonction initData ci-dessus est exécutée lors de la construction du composant, elle ne sera donc exécutée qu'une seule fois lors de la création. C'est pourquoi la documentation officielle dit "transmettre comme valeur initiale", car elle ne sera exécutée qu'une seule fois. Lorsque le composant est construit, il n'y a aucune relation entre this.tableData et tData. Les modifications dans l'un n'entraîneront pas de modifications dans l'autre. Bien sûr, cette affirmation n'est pas exacte, car dans ce qui précède, nous modifions dynamiquement le total transmis par le composant parent, et les composants enfants changent également « en même temps ». ?

3. Illusions provoquées par les types de référence

Bien sûr, il faut encore partir des documents officiels pour résoudre ce problème. Il y a une telle astuce dans le document :

这里就需要理解引用类型的概念,引用数据类型值指保存在堆内存中的对象。也就是,变量中保存的实际上的只是一个指针,这个指针指向内存中的另一个位置,该位置保存着对象。访问方式是按引用访问。例如一个js对象a,他在内存中的存储形式如下图所示:

var a = new Object();

当操作时,需要先从栈中读取内存地址,然后再延指针找到保存在堆内存中的值再操作。

a.name = &#39;xz&#39;;


引用类型变量赋值,本质上赋值的是存储在栈中的指针,将指针复制到栈中未新变量分配的空间中,而这个指针副本和原指针指向存储在堆中的同一个对象;赋值操作结束后,两个变量实际上将引用同一个对象。因此,在使用时,改变其中的一个变量的值,将影响另一个变量。

var b = a;


在了解了引用类型之后,我们在来看看上文提到的动态改变传入子组件前后内存中的情况:

me.tableData = Json.data.restrictioninfo;
me.pageInfo.total = Json.data.total;
========================================
props: [&#39;tableData&#39;, &#39;pageInfo&#39;],
data() {
 return {
  tData: this.tableData,
  page: this.pageInfo
 }
}

首先对tableData的改变是改变了其引用的指针,而对pageInfo则改变了其中一个属性的值,因此动态改变前:

动态改变后:

这样就解释了为什么子组件页面的总数更新了,但table数据依然是初始化时的空数组。因为引用类型的存在,我们动态改变父组件传入的total,子组件也"随之"改变了。

上面是我整理给大家的,希望今后会对大家有帮助。

相关文章:

在jQuery中如何实现点击DIV触发点击CheckBox

使用JS如何实现点击复选框修改显示状态

在Vue中标准的处理方法(详细教程)

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!

Déclaration:
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