Vue: 予期しない「スロットの重複存在」

作成日 2018年03月28日  ·  9コメント  ·  ソース: vuejs/vue

バージョン

2.5.2

複製リンク

https://codesandbox.io/s/mzvkppmvo8

再現する手順

  1. スコープスロット(AppSwitcher.vue)でコンポーネントを作成しました
  2. 次に、独自のスロットを持つ別のコンポーネントで使用します(HelloWorld.vueとスロット "subtext")
  3. スロットに要素を追加します(App.vueのdiv)

何が期待されますか?

エラーなしで動作するはずです

実際に何が起こっているのですか?

AppSwitcher.vueの変更により、「同じレンダーツリーでスロット「サブテキスト」が重複して存在する」エラーが発生しましたが、重複はありません。


また、App.vueのdivにslot-scopeを追加すると、問題は解決し、エラーは発生しませんが、 slot-scopeなしで発生するの

bug has PR

最も参考になるコメント

私も同じことを経験しています。 スロットスコープ内で再レンダリングをトリガーするものはすべて、重複スロットの存在に関する警告を引き起こします。

問題はここのこの行にあるようです。 スロットが一度レンダリングされると、そのブロックの後続の実行では、おそらく最初のレンダリングから、 slotNodes._renderedがtrueになります。

再レンダリングがトリガーされたときに何かがfalseに戻るはずだと想像しますが、確かに、Vueが内部でどのように機能するかについてはほとんど何も知らないので、それは単なる推測です。

このバグはありそうもないエッジケースのように見えますが、最近数回私に起こりました。 私は具体的な実装と組み合わせることができるレンダリングレスコンポーネントを作成するパターンの大ファンであり、コンシューマーから具体的な実装にコンテンツを渡そうとすると、この問題が発生します。

全てのコメント9件

こんにちは@ Kelin2025

v2.5では、 scoped-slotにいくつかの変更がありました。ここで、それらを確認できます-https

これはあなたの混乱を解決するかもしれません

ええ、私はそれを知っていますが、なぜこのエラーが発生するのか本当にわかりません。スロットの__duplicates__はなく、再レンダリングするだけです。

スコープスロット内のスロットが複数回レンダリングされているように見えます。

@Justineo変更時に再レンダリングされていますが、問題が発生することはないはずです。:thinking:

私の2セント。

これは、この問題の別の複製です(https://codesandbox.io/s/m5kl6p97qx)。 モーダルが複数回表示された場合にのみ警告が表示されることに注意してください。

一方、同じコンポーネントのJSXバージョンは警告を発していません(https://codesandbox.io/s/k0wpj60z5r)。

私も同じことを経験しています。 スロットスコープ内で再レンダリングをトリガーするものはすべて、重複スロットの存在に関する警告を引き起こします。

問題はここのこの行にあるようです。 スロットが一度レンダリングされると、そのブロックの後続の実行では、おそらく最初のレンダリングから、 slotNodes._renderedがtrueになります。

再レンダリングがトリガーされたときに何かがfalseに戻るはずだと想像しますが、確かに、Vueが内部でどのように機能するかについてはほとんど何も知らないので、それは単なる推測です。

このバグはありそうもないエッジケースのように見えますが、最近数回私に起こりました。 私は具体的な実装と組み合わせることができるレンダリングレスコンポーネントを作成するパターンの大ファンであり、コンシューマーから具体的な実装にコンテンツを渡そうとすると、この問題が発生します。

これを試して:
my-component:

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

アプリ:

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

特に「v-for」の「slot」の場合

Vue.js≤v2.4.xを使用している場合、 slot-scopeを使用しようとすると、このエラーが表示される場合があることに注意してください(これが私に起こっていたことです)。

解決策は、Vue.jsを2.5以上に更新するか、「slot-scope」の代わりに「scope」を使用することです。

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

私がしたように、他の誰かがグーグルでこれを見つけるのを助けることを願っています!


PS。 Vue.js≤v2.4.xを使用している場合は、 <template>要素を使用する必要があることに注意してください。2.5以上になるまで、その他の要素にスロットスコープの境界を設定することはできません。 。バツ。 少し実例:

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

解決策は、Vue.jsを2.5以上に更新するか、「slot-scope」の代わりに「scope」を使用することです。

私はまだ2.5.17この問題を抱えています。

レンダーレスコンポーネントの抽象化を構築しようとすると、非常に頻繁に発生するため、非常に面倒です。

このページは役に立ちましたか?
0 / 5 - 0 評価