Vue: "Présence en double de l'emplacement" inattendue

Créé le 28 mars 2018  ·  9Commentaires  ·  Source: vuejs/vue

Version

2.5.2

Lien de reproduction

https://codesandbox.io/s/mzvkppmvo8

Étapes à suivre pour reproduire

  1. J'ai créé un composant avec un slot scoped (AppSwitcher.vue)
  2. Ensuite, je l'utilise dans un autre composant avec leur propre slot (HelloWorld.vue avec slot "subtext")
  3. Ajouter un élément à l'emplacement (div dans App.vue)

Qu'attend-on?

Cela devrait fonctionner sans erreur

Que se passe-t-il réellement?

Les modifications apportées à AppSwitcher.vue provoquent l'erreur "Présence en double du sous-texte" de l'emplacement trouvé dans la même arborescence de rendu ", mais il n'y a pas de doublons.


De plus, ajouter slot-scope à div dans App.vue résout le problème et aucune erreur là-bas, mais pourquoi cela se produit sans slot-scope ?

bug has PR

Commentaire le plus utile

Je vis la même chose. Tout ce qui déclenche un nouveau rendu à l'intérieur de la portée de l'emplacement provoque un avertissement concernant la présence d'un emplacement en double.

Le problème semble être ici sur cette ligne ici . Une fois que les slots ont été rendus une fois, les exécutions ultérieures de ce bloc ont slotNodes._rendered comme vrai, probablement à partir du premier rendu.

J'imagine que quelque chose devrait redéfinir cela sur false lorsqu'un nouveau rendu est déclenché, mais il est vrai que je ne sais presque rien sur le fonctionnement de Vue sous le capot, ce n'est donc qu'une supposition sauvage.

Ce bug semble être un cas limite improbable, mais cela m'est arrivé plusieurs fois récemment. Je suis un grand fan du modèle d'écriture de composants sans rendu qui peuvent être associés à des implémentations concrètes, et essayer de transmettre le contenu du consommateur à l'implémentation concrète est le moment où ce problème se pose.

Tous les 9 commentaires

Bonjour @ Kelin2025

Dans la version 2.5, il y a eu quelques changements dans scoped-slot , vous pouvez les parcourir ici - https://gist.github.com/yyx990803/9bdff05e5468a60ced06c29c39114c6b#simplified -scoped-slots-usage

Cela pourrait résoudre votre confusion

Ouais, je le sais, mais je ne comprends pas vraiment pourquoi j'obtiens cette erreur, il n'y a pas de __duplicates__ de slot mais seulement un rendu.

Il semble qu'un emplacement à l'intérieur d'un emplacement à portée est rendu plus d'une fois.

@ Justineo, il est en train d'être rendu sur les changements mais cela ne devrait pas poser de problèmes, je pense: penser:

Mes 2 cents.

Voici une autre reproduction de ce numéro (https://codesandbox.io/s/m5kl6p97qx). Notez que l'avertissement n'est déclenché qu'une fois que le modal est affiché plus d'une fois.

En revanche, la version JSX du même composant ne lève aucun avertissement (https://codesandbox.io/s/k0wpj60z5r).

Je vis la même chose. Tout ce qui déclenche un nouveau rendu à l'intérieur de la portée de l'emplacement provoque un avertissement concernant la présence d'un emplacement en double.

Le problème semble être ici sur cette ligne ici . Une fois que les slots ont été rendus une fois, les exécutions ultérieures de ce bloc ont slotNodes._rendered comme vrai, probablement à partir du premier rendu.

J'imagine que quelque chose devrait redéfinir cela sur false lorsqu'un nouveau rendu est déclenché, mais il est vrai que je ne sais presque rien sur le fonctionnement de Vue sous le capot, ce n'est donc qu'une supposition sauvage.

Ce bug semble être un cas limite improbable, mais cela m'est arrivé plusieurs fois récemment. Je suis un grand fan du modèle d'écriture de composants sans rendu qui peuvent être associés à des implémentations concrètes, et essayer de transmettre le contenu du consommateur à l'implémentation concrète est le moment où ce problème se pose.

essaye ça:
mon-composant:

<template>
    <slot :someprop="value"></slot>
</template>

application:

<my-component>
    <template slot-scop="someprop">{{ prop }} ... and do something else</template>
</my-component>

surtout quand "slot" dans "v-for"

Notez que si vous utilisez Vue.js ≤v2.4.x, vous pouvez voir cette erreur si vous essayez d'utiliser slot-scope (c'est ce qui se passait pour moi).

La solution est de mettre à jour Vue.js à ≥2.5 OU d'utiliser "scope" au lieu de "slot-scope":

image
_ https://vuejs.org/v2/api/#scope -replaced_

J'espère que cela aidera quiconque à trouver cela sur Google comme je l'ai fait!


PS. Si vous utilisez Vue.js ≤v2.4.x, rappelez-vous que vous devrez utiliser un élément <template> - vous ne pouvez pas simplement mettre une limite de portée de slot sur n'importe quel élément divers jusqu'à ≥2.5 .X. Un petit exemple du monde réel:

      <div class="form-group col-md">
        <label>Autocomplete field 4 (w/ custom search results):</label>
        <autocomplete v-model="autocompleteExampleValue4" action="listGlobalSearchResults" :handle-formatting-response-data="handleFormattingDummySearchResults" placeholder="This one has a custom placeholder too">
          <template slot="search-result-item" scope="slotData"><!-- Note that you can use destructuring here, but it only works in modern browsers -- otherwise you have to define a separate variable -- like scope="slotData" and then use {{slotData.id}}... (see https://vuejs.org/v2/guide/components-slots.html#Destructuring-slot-scope) -->
            <!-- TODO: update to vue ≥ 2.5.0 to allow this slotData thing to be attached w/o using a template element.  Also when we do that, "scope" will become "slot-scope".  See https://vuejs.org/v2/guide/components-slots.html#Scoped-Slots for more info -->
            <span>{{slotData.searchResult.label}}</span>
          </template>
        </autocomplete>
      </div>

La solution est de mettre à jour Vue.js à ≥2.5 OU d'utiliser "scope" au lieu de "slot-scope":

J'ai toujours ce problème sur 2.5.17 .

C'est vraiment ennuyeux d'essayer de créer des abstractions de composants sans rendu, car cela revient assez souvent.

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