0

次のコードがあります。2 つのコンポーネントを使用しています。1 つはMustachesと呼ばれ、もう 1 つはMustacheと呼ばれます。

を使用して、Mustaches内のMustacheからのデータを表示しようとしています。v-for

データやエラーが表示されません。Mustaches html はソース コードに表示されますが、Mustacheデータには表示されません。

HTML

<div id="app">
    <moustaches>
        <moustache name="The Burgundy" img="/img/the-burgundy.jpg"></moustache>
        <moustache name="The Borat" img="/img/the-borat.jpg"></moustache>
        <moustache name="The Santana" img="/img/the-santana.jpg"></moustache>
    </moustaches>
</div>

JS

    Vue.component('moustaches', {
    template: `
        <div>
            <ul class="list-inline">
                <li v-for="moustache in moustaches">
                    <p>
                        <strong>@{{ moustache.name }}</strong>
                    </p>
                    <img width="300" height="200" :src="moustache.img">
                    <button 
                        class="btn btn-primary" 
                        :data-type="moustache.name"
                        >
                            Vote
                    </button>
                </li>
            </ul>
        </div>
    `,

    mounted() {
        console.log(this.$children);
    },

    data() {
        return { moustaches: [] };
    },

    created() {
        this.moustaches = this.$children;
      }
});

Vue.component('moustache', {
    template: `
        <div><slot></slot></div>
    `,

    props: {
        name: { required: true },
        img: { required: true},
        selected: { default: false }
    }

});

new Vue({
    el: '#app'
});

レンダリングされた HTML

<div><ul class="list-inline"></ul></div>
4

2 に答える 2

2

私はあなたが達成しようとしていることを 100% 理解しているわけではありませんが、スロットの仕組みを誤解していると思います。

スロット

<slot>要素を使用すると、コンテンツをコンポーネントに配布できます。以下に小さな例を示します。

Vue.component('child-component', {
  template: '#child-component'
});

new Vue({
  el: '#app',
  data: { message: 'Hello I have been slotted' }
});
  
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.1.4/vue.js"></script>
<div id="app">
  <child-component>
    {{ message }}
  </child-component>
</div>

<template id="child-component">
  <div>
    <p>Above the slot</p>
    <slot></slot>
    <p>Below the slot</p>
  </div>
</template>

基本的に、コンポーネント タグ間のすべての html がスロットに配置されます。スロットの詳細については、こちらのドキュメントを参照してください

問題

3 つの口ひげコンポーネントを口ひげに挿入しようとしましたが、口ひげにはスロットがありません。

また、口ひげのコンポーネント スロットを指定しましたが、何もスロットには入れていません。

解決策 1

コンポーネントにスロットを追加しmoustachesます。コンポーネントは空の div であるためmoustache、ページには表示されません。以下は実際のコード スニペットです。

Vue.component('moustaches', {
  template: '#moustaches',
  data() {
    return { moustaches: [] };
  },
  created() {
    this.moustaches = this.$children;
  }
});

Vue.component('moustache', {
  template: '<div><slot></slot></div>',

  props: {
    name: { required: true },
    img: { required: true},
    selected: { default: false }
  }

});

new Vue({
  el: '#app'
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.1.4/vue.js"></script>

<div id="app">
  <moustaches>
    <moustache name="The Burgundy" img="/img/the-burgundy.jpg"></moustache>
    <moustache name="The Borat" img="/img/the-borat.jpg"></moustache>
    <moustache name="The Santana" img="/img/the-santana.jpg"></moustache>
  </moustaches>
</div>

<template id="moustaches">
  <div>
    <ul class="list-inline">
      <li v-for="moustache in moustaches">
        <p>
          <strong>@{{ moustache.name }}</strong>
        </p>
        <img width="300" height="200" :src="moustache.img">
        <button 
                class="btn btn-primary" 
                :data-type="moustache.name"
                >
          Vote
        </button>
      </li>
    </ul>
    <slot></slot>
  </div>
</template>

スロットはデータを渡すためだけに使用しているため、このアプローチはお勧めしません。スロットは、データではなく html を渡すために使用する必要があります。これは奇妙なやり方であり、他のバグに遭遇する可能性があります。

解決策 2

スロットを使用してデータを渡す代わりに、小道具を介してデータを渡す必要があります。moustacheデータを html から親コンポーネントに移動することで、すべてのスロットとコンポーネントを完全に取り除くことができます。

Vue.component('moustaches', {
  template: '#moustaches',
  props: ['moustaches'],
});

new Vue({
    el: '#app',
    data: {
    	moustaches: [
        { name: "The Burgundy", img: "/img/the-burgundy.jpg" },
        { name: "The Borat", img: "/img/the-borat.jpg" },
        { name: "The Santana", img: "/img/the-santana.jpg" },
      ]
    }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.1.4/vue.js"></script>

<div id="app">
  <moustaches :moustaches="moustaches"></moustaches>
</div>

<template id="moustaches">
  <div>
    <ul class="list-inline">
      <li v-for="moustache in moustaches">
        <p>
          <strong>@{{ moustache.name }}</strong>
        </p>
        <img width="300" height="200" :src="moustache.img">
        <button 
                class="btn btn-primary" 
                :data-type="moustache.name"
                >
          Vote
        </button>
      </li>
    </ul>
  </div>
</template>

于 2016-12-07T00:29:10.443 に答える
0

上記の投稿者は、私ができるよりもはるかにうまく質問に親切に答えてくれましたが、TL:DR の答えは<slot></slot>Mustachesコンポーネントに欠けていたということです。

終了divの下に追加したところ、うまくいきました。

于 2016-12-07T00:51:15.880 に答える