web-dev-qa-db-ja.com

繰り返しコンテンツ領域に<slot>を追加する

簡単に言えば、オプションの配列を持つ小道具を​​取り込んで、それぞれのメニューの項目をレンダリングするメニューコンポーネントがあります。ユースケースに応じて各メニュー項目内にあるマークアップをカスタマイズできるようにしたかったので、メニュー項目要素内のプレースホルダーを使用しました。

この例は、この fiddle で確認できます。

const Menu = {
    template: `
        <ul>
            <li v-for="item in options" :class="item.colour">
            <slot></slot>
            <span class="label">{{item.name}}</span>
          </li>
        </ul>
    `,
    data: () => {
        return {
            options: [
                { name: 'one', colour: 'red' },
                { name: 'two', colour: 'green' },
                { name: 'three', colour: 'blue' },
                { name: 'four', colour: 'yellow' }
            ]
       };
    }
};


const app = new Vue({
    components: {
        custommenu: Menu,
      },
    template: `<custommenu><span class="colour"></span></custommenu>`
});

app.$mount('#app');

これはVue.JSのv1で正常に機能しましたが、v2にアップグレードした後、「同じレンダリングツリーにスロット「デフォルト」が重複して存在します。これによりレンダリングエラーが発生する可能性があります」というエラーが表示されます。

これはv2で可能なことですか、それとも同じことを実現する別の方法がありますか?

9
Stuart

これには スコープスロット が必要なようです。そのため、slot属性を持つテンプレートでscopeコンテンツをラップする必要があります。

<custommenu>
  <template scope="colour">
    <span class="colour"></span>
  </template>
</custommenu>

次に、それをコンポーネントテンプレートのスロットに追加する必要があります。

<ul>
  <li v-for="item in options" :class="item.colour">
    <slot colour></slot>
    <span class="label">{{item.name}}</span>
  </li>
</ul>

更新されたJSFiddleは次のとおりです。 https://jsfiddle.net/kLge4wun/

10
craig_h