Vue: Prend en charge plus de types de données de collecte dans v-for

Créé le 28 févr. 2016  ·  39Commentaires  ·  Source: vuejs/vue

Dans certaines situations, l'objet simple n'est pas le meilleur choix. J'ai essayé de rendre un objet Map par v-for , mais il semble que Vue ne le supporte pas actuellement. (Voici un message que j'ai créé dans le fil d'aide du forum.)

J'espère que Vue peut fournir la syntaxe for ... of dans v-for pour itérer sur des types de données comme Map et Set .

Par example:

const map = new Map();
map.set('key1', 'val1');
map.set('key2', 'val2');

et nous pouvons rendre map de cette manière :

<ul>
    <li v-for="[key, val] of map">{{key}} - {{val}}</li>
</ul>
feature request

Commentaire le plus utile

Il est important de pouvoir itérer sur les itérateurs en boucles. Cela semble bien évident. C'est une caractéristique fondamentale de la langue.

Les raisons de le soutenir sont :

1) Les itérateurs, les cartes et les ensembles sont tous ES6 valides. Refuser de les soutenir, c'est se limiter à l'ES5, qui est une décision de moins en moins justifiée avec le temps.
2) Je construis une application qui contient des données internes stockées dans Maps and Sets. Au lieu de les mettre à la disposition de l'interface utilisateur, je dois maintenant garder les données synchronisées entre les deux manuellement, ou écrire un texte passe-partout et l'importer dans mes modèles pour effectuer la conversion chaque fois que les données sont nécessaires. C'est exactement ce que Vue est censé éviter.

Tous les 39 commentaires

Un duplicata de https://github.com/vuejs/vue/issues/1319

@wenLiangcan , vous pouvez utiliser quelque chose comme ceci :

<ul>
    <li v-for="[key, val] of get(map)">{{key}} - {{val}}</li>
</ul>

get() est votre fonction.

haha ! des problèmes similaires s'ouvrent tout le temps et et les gens insistent sur le fait qu'ils ne peuvent pas justifier la mise en œuvre, les gens veulent bien l'utiliser, c'est une justification. J'en ai également trouvé un qui justifie très bien le cas d'utilisation et fait référence à la spécification es6 en ce qui concerne l'ordre des cartes ->toujours fermé.

Les personnes souhaitant utiliser une fonctionnalité n'est pas, en soi, un argument qui peut justifier la nécessité d'avoir une telle fonctionnalité, il est nécessaire de peser le coût et les avantages (quel problème est résolu) de l'ajout d'une telle fonctionnalité

Oui mais toujours les arguments que les gens utilisent pour clore le problème ne sont toujours pas valables ou du moins pas valables pour tous les cas d'utilisation, par exemple l'exemple d'elipen qui a très bien justifié ses cas d'utilisation comme je l'ai mentionné ci-dessus

Si vous souhaitez discuter d'un problème spécifique, créez un lien vers celui-ci s'il vous plaît.

De plus, ce problème de fonctionnalité est ouvert. Cela n'a pas de sens d'avoir plus d'un problème ouvert pour la même demande.

Il est important de pouvoir itérer sur les itérateurs en boucles. Cela semble bien évident. C'est une caractéristique fondamentale de la langue.

Les raisons de le soutenir sont :

1) Les itérateurs, les cartes et les ensembles sont tous ES6 valides. Refuser de les soutenir, c'est se limiter à l'ES5, qui est une décision de moins en moins justifiée avec le temps.
2) Je construis une application qui contient des données internes stockées dans Maps and Sets. Au lieu de les mettre à la disposition de l'interface utilisateur, je dois maintenant garder les données synchronisées entre les deux manuellement, ou écrire un texte passe-partout et l'importer dans mes modèles pour effectuer la conversion chaque fois que les données sont nécessaires. C'est exactement ce que Vue est censé éviter.

Puisque le #1319 est fermé, cela vaut la peine de réitérer la décision actuelle ici. Bref, la fonctionnalité n'est pas triviale à mettre en œuvre (au niveau du mécanisme d'observation), il ne s'agit donc pas de justifier des cas d'utilisation, mais de la quantité de travail et de compromis.

J'apprécierais vraiment cette fonctionnalité aussi. D'un autre côté, si l'observation des types de données ES6 devient terriblement difficile ou, par exemple, compromet les performances ou d'autres qualités, alors les personnes qui n'utilisent pas actuellement Maps and Sets avec Vue pourraient ne pas apprécier ce changement.

Je suppose que l'utilisation de Array.from() dans une fonction calculée devra être votre meilleur ami pour le moment. :désappointé:

Une solution pour ça ?

Petite mise à jour, cela viendra si/quand Vue décide d'abandonner les navigateurs "anciens" et passera à Evergreen avec Proxy au lieu de set / get pour la réactivité.

@alexsandro-xpt, utilisez simplement une fonction calculée qui renvoie Array.from(yourDataSet) .

@nickmessing J'essaie avec Map, ne fonctionne pas.
La valeur de longueur de tableau calculée est toujours 0.

Juste Array.from n'est probablement pas la solution que vous souhaitez en raison du manque de réactivité (les modifications apportées à yourDataSet ne seront pas propagées à Vue).

Comme mentionné précédemment, les ensembles et les cartes ne sont pas observables par Vue. Afin de les utiliser — soit dans v-for , soit dans des propriétés calculées, des méthodes, des observateurs, des expressions de modèle, etc. — vous devez créer une réplique sérialisable de cette structure et l'exposer à Vue. Voici un exemple naïf qui utilise un simple compteur pour fournir à Vue des informations indiquant que Set est mis à jour :

data() {
  mySetChangeTracker: 1,
  mySet: new Set(),
},

computed: {
  mySetAsList() { 
    // By using `mySetChangeTracker` we tell Vue that this property depends on it,
    // so it gets re-evaluated whenever `mySetChangeTracker` changes
    return this.mySetChangeTracker && Array.from(this.mySet);
  },
},

methods: {
  add(item) {
    this.mySet.add(item);
    // Trigger Vue updates
    this.mySetChangeTracker += 1;
  }
}

Cela illustre une méthode de travail un peu bidon mais à 100% pour rendre réactives les données non observables. Pourtant, dans des cas réels, je me suis retrouvé avec des versions sérialisées de Sets/Maps (par exemple, vous voudriez probablement stocker les versions modifiées de sets/maps dans un stockage local et ainsi les sérialiser de toute façon), donc aucun compteur/piratage artificiel n'a été impliqué.

Personnellement, je pense que c'est une solution juste à un problème, mais cela mérite certainement une documentation officielle - sinon, il est impossible de justifier cela comme un moyen non piraté de traiter les internes de Vue.

@alexsandro-xpt, désolé, je me suis trompé, le calcul sera piraté comme l' @inca , une autre solution $forceUpdate avec une méthode, voici un exemple de violon

Merci @nickmessing et @inca , ça marche bien avec mon new Map() !!

À l'heure actuelle, lorsque vous effectuez un "v-for" sur une "Map", le v-for agit comme s'il avait reçu un tableau vide.

Quel que soit le résultat de la discussion prolongée sur la prise en charge des cartes et des ensembles, cela permettrait à beaucoup de gens d'économiser beaucoup de temps de débogage si Vue avertissait simplement "Les cartes et les ensembles ne sont pas encore pris en charge -- voir https://github .com/vuejs/vue/issues/2410 ".

Oui, la recherche Google pour cette fonctionnalité m'a amené à ce ticket (après quelques confusions ennuyeuses avec Vue.set)

Cela devrait être dans la documentation v-for !

Vraiment, devrait être dans v-for documentation !

/cc @chrisvfritz essayons d'ajouter une note sur la prise en charge de ces types dans la documentation pour v-for (à la fois l'API et la section de rendu de liste) - je les examinerai également dans 2.5.

@ yyx990803 Je me demande si un avertissement de console ne serait pas mieux pour cela, car cela indiquerait immédiatement aux gens ce qui ne va pas, évitant ainsi le besoin de rechercher la solution.

Nous sommes également déjà très explicites dans la documentation sur les types que nous prenons en charge, Map et Set n'en faisant pas partie. Je peux certainement voir l'argument pour lequel on pourrait _espérer_ que tous les itérables fonctionneraient avec v-for , mais je ne pense pas que nous donnions actuellement aux lecteurs aucune raison de s'attendre à ce qu'ils le fassent.

Je ne vois pas vraiment l'argument contre l'ajout de la prise en charge de Set .

Set lui-même peut être proprement polyrempli, et à moins que quelque chose ne me manque, il semble que l'approche de Vue pour ajouter de la réactivité aux tableaux puisse très facilement être étendue aux ensembles. Nous aurions seulement besoin d'envelopper .add() , .clear() et .delete() .

Ma meilleure supposition (veuillez corriger/désolé si je me trompe) : la partie la plus délicate consiste à envelopper un constructeur Set , qui accepte un itérable. Je ne vois pas comment itérable peut être rendu observable, car dans sa forme générale, c'est juste une fonction (c'est- next dire

Pourquoi devons-nous envelopper le constructeur ? Ne passerions-nous pas des ensembles préexistants dans Vue ?

Selon la spécification , le constructeur Set parcourt immédiatement l'ensemble de l'itérateur, conservant efficacement une copie superficielle des éléments uniques renvoyés par l'itérateur. Une fois que vous avez une instance Set , peu importe qu'elle ait été créée à partir d'un itérateur ou non.

À cet égard, un Set créé à partir d'un itérateur ne devrait pas être différent d'un tableau créé à partir d'un itérateur (via Array.from() ), que Vue prend déjà en charge.

Vous pouvez utiliser des Maps/sets/n'importe quelles structures de données immuables et autoriser la réactivité avec elles, mais simplement parce que toute la référence du morceau change. Vous pouvez les rendre via une fonction de rendu ou un tableau généré calculé (le premier étant meilleur en termes de performances car il ignore la création d'un tableau..). Mais les structures de données mutables, pas le cas, à moins que vous ne trouviez un moyen d'informer manuellement Vue des modifications spécifiques, ce qui serait simplement une solution maison pour votre propre année.

Ce n'est pas bon. Tu ne peux pas le faire

@wenLiangcan

var map = new Map()
  map.set('key1','Test1')
  map.set('key2','Test2')
        <div class="file-size">{{value}}</div>
 </div>

Non, il n'apparaît pas sur la page

Désireux de soutenir cela :)

Moi aussi

Avez-vous l'intention d'ajouter du support à l'avenir ? Y a-t-il une raison technique pour laquelle Vue n'a pas pu prendre en charge Map and Set ?

Le problème actuel avec la méthode Vue.set sur un objet simple est qu'elle déclenche beaucoup trop d'abonnés lorsqu'une propriété est ajoutée à l'objet. En fait, tous les abonnés de toutes les propriétés sont déclenchés lorsqu'une seule propriété est ajoutée.

Les performances de la vue sont fortement impactées lorsqu'une carte comme une collection contient des centièmes de clés. Par exemple, dans mon projet, des milliers d'abonnés sont déclenchés lorsqu'un élément est ajouté à la carte à l'aide de l'opération Vue.set :

Vue.set(state.items, itemId, item); // where items is a plain object.

Lorsque je regarde en profondeur le code Vue.js, je peux voir d'où vient le problème. Les dépendances qui sont déclenchées sont celles de l'objet, ce qui signifie que si l'objet a une propriété pour chaque clé, alors toutes les dépendances de toutes les clés sont déclenchées lors de l'ajout d'une seule clé.

Ainsi, utiliser des objets simples pour imiter une carte ne semble pas être la bonne solution. Par conséquent, la prise en charge d'une carte en vue est plus que bienvenue pour les grandes collections d'éléments.

Y a-t-il des nouvelles sur les projets futurs et éventuellement sur le support natif Map/Set ?

Cet article détaille le support à venir dans 2.6 - mais il n'y a rien à ce sujet dans la feuille de route officielle d'après ce que je peux voir ?

https://medium.com/@alberto.park/the -status-of-javascript-libraries-frameworks-2018-beyond-3a5a7cae7513

« La dernière version actuelle du noyau est 2.5.x. La prochaine version mineure (v2.6) prendra en charge l'importation ESM native, la gestion améliorée des erreurs asynchrone, l'itérateur sur la directive 'v-for' et plus encore. »

Vous ne savez pas d'où ils ont obtenu ces informations ?

J'ai trouvé ce problème lors du débogage du comportement de Vue sur les objets de données Set . :en pensant:

Pour les gens comme moi qui se posaient des questions sur la feuille de route pour cela, Evan You dit dans cette vidéo que le support de Map and Set est "probable" d'arriver dans la 2.6, mais c'était en mai, donc c'est tout ce que je sais.

@ yyx990803 Il est regrettable que ce problème dans le tracker soit marqué comme fermé, surtout si vous envisagez d'ajouter une prise en charge dans un proche avenir. Où pouvons-nous suivre les progrès de cette fonctionnalité ? Il y a un autre problème quelque part ?

Je me demande juste pour le plaisir de l'argument, et peut-être que je le fais mal, mais puisque vous pouvez suivre la mutation du tableau à l'aide des méthodes de mutation, ne pouvez-vous pas simplement suivre un tableau d'un objet et être logiquement complet ? vous n'obtenez pas toutes les mêmes fonctionnalités implémentées dans Map, mais celles que vous voulez seraient assez facilement traitées, surtout si vous utilisez quelque chose comme _ ou lodash.

C'est triste, mais jusqu'à ce que l'équipe ajoute cela, nous devrons peut-être utiliser des structures de données alternatives

Je veux juste souligner que nous allions utiliser une carte pour notre structure de données, puis nous avons décidé de ne pas le faire en raison d'un manque de support de première partie.

est-ce pris en charge maintenant dans Vue3 (c'est-à-dire réactifs Map et Set ) ?

Cette page vous a été utile?
0 / 5 - 0 notes