Vue: "Presença duplicada de slot" inesperada

Criado em 28 mar. 2018  ·  9Comentários  ·  Fonte: vuejs/vue

Versão

2.5.2

Link de reprodução

https://codesandbox.io/s/mzvkppmvo8

Passos para reproduzir

  1. Criei um componente com slot de escopo (AppSwitcher.vue)
  2. Então eu uso em outro componente com seu próprio slot (HelloWorld.vue com slot "subtexto")
  3. Adicione algum elemento ao slot (div em App.vue)

O que é esperado?

Deve funcionar sem erros

O que realmente está acontecendo?

Alterações em AppSwitcher.vue causam o erro "Presença duplicada de slot" subtexto "encontrado na mesma árvore de renderização", mas não há duplicatas.


Além disso, adicionar slot-scope a div em App.vue resolve o problema e nenhum erro, mas por que isso acontece sem slot-scope ?

bug has PR

Comentários muito úteis

Estou experimentando a mesma coisa. Qualquer coisa que acione uma nova renderização dentro do escopo do slot causa um aviso sobre a presença de slot duplicado.

O problema parece estar aqui nesta linha aqui . Uma vez que os slots tenham sido renderizados uma vez, as execuções subsequentes desse bloco têm slotNodes._rendered como verdadeiras, presumivelmente desde a primeira renderização.

Eu imaginaria que algo deveria ser definido como falso quando uma nova renderização é acionada, mas admito que não sei quase nada sobre como o Vue funciona sob o capô, então isso é apenas um palpite.

Esse bug parece um caso extremo improvável, mas aconteceu comigo algumas vezes recentemente. Eu sou um grande fã do padrão de escrever componentes sem render que podem ser combinados com implementações concretas, e tentar passar o conteúdo do consumidor para a implementação concreta é quando esse problema está surgindo.

Todos 9 comentários

Olá @ Kelin2025

Na v2.5, houve algumas alterações em scoped-slot , você pode verificá-las aqui - https://gist.github.com/yyx990803/9bdff05e5468a60ced06c29c39114c6b#simplified -scoped-slots-usage

Isso pode resolver sua confusão

Sim, eu sei disso, mas eu realmente não entendo porque recebo esse erro, não há __duplicados__ de slot, mas apenas rerender.

Parece que um slot dentro de um slot com escopo é renderizado mais de uma vez.

@Justineo está sendo

Meus 2 centavos.

Aqui está outra reprodução deste problema (https://codesandbox.io/s/m5kl6p97qx). Observe o aviso sendo gerado apenas quando o modal é mostrado mais de uma vez.

Por outro lado, a versão JSX do mesmo componente não está gerando nenhum aviso (https://codesandbox.io/s/k0wpj60z5r).

Estou experimentando a mesma coisa. Qualquer coisa que acione uma nova renderização dentro do escopo do slot causa um aviso sobre a presença de slot duplicado.

O problema parece estar aqui nesta linha aqui . Uma vez que os slots tenham sido renderizados uma vez, as execuções subsequentes desse bloco têm slotNodes._rendered como verdadeiras, presumivelmente desde a primeira renderização.

Eu imaginaria que algo deveria ser definido como falso quando uma nova renderização é acionada, mas admito que não sei quase nada sobre como o Vue funciona sob o capô, então isso é apenas um palpite.

Esse bug parece um caso extremo improvável, mas aconteceu comigo algumas vezes recentemente. Eu sou um grande fã do padrão de escrever componentes sem render que podem ser combinados com implementações concretas, e tentar passar o conteúdo do consumidor para a implementação concreta é quando esse problema está surgindo.

tente isto:
meu-componente:

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

aplicativo:

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

especialmente quando "slot" em "v-for"

Observe que se você estiver usando Vue.js ≤v2.4.x, poderá ver este erro se estiver tentando usar slot-scope (isso é o que estava acontecendo comigo).

A solução é atualizar Vue.js para ≥2,5 OU usar "scope" em vez de "slot-scope":

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

Espero que ajude alguém a encontrar isso no google como eu fiz!


PS. Se você estiver usando Vue.js ≤v2.4.x, lembre-se de que você precisará usar um elemento <template> - você não pode simplesmente colocar um limite de escopo de slot em qualquer elemento diverso até ≥2,5 .x. Um pequeno exemplo do mundo real:

      <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>

A solução é atualizar Vue.js para ≥2,5 OU usar "scope" em vez de "slot-scope":

Ainda tenho esse problema em 2.5.17 .

É realmente irritante quando se tenta construir abstrações de componentes sem render, pois isso acontece com frequência.

Esta página foi útil?
0 / 5 - 0 avaliações

Questões relacionadas

seemsindie picture seemsindie  ·  3Comentários

finico picture finico  ·  3Comentários

paceband picture paceband  ·  3Comentários

bfis picture bfis  ·  3Comentários

aviggngyv picture aviggngyv  ·  3Comentários