2017-02-22 23 views
1

vue js 2を使用して展開可能なアイテムを含むリストを作成しようとしています。アイテムをクリックして展開したい(コンテンツを表示する)まだ展開されていない場合は、他のすべての拡張要素を閉じます。私はexpandable-panelexpandable-itemという2つのコンポーネントを作成しました。内部には複数のタイプのコンテンツがあるので、スロットを使いたい。子コンポーネントが親と親に放出され、すべての子コンポーネントが更新されます

私が持っているコード:

ExpandablePanelコンポーネント:

<template> 
    <div class="expandable-panel" @expanded="doStuff"> 
     <slot></slot> 
    </div> 
</template> 

<script type="text/babel"> 
    export default { 
     methods: { 
      doStuff: function() { 
       alert('expanded'); 
      } 
     } 
    } 
</script> 

ExpandableItemコンポーネント:

<template> 
    <div class="expandable-item" @click="toggleExpand"> 
     <div class="expandable-item-header"> 
      {{ title }} 
     </div> 
     <div class="expandable-item-body" v-if="expanded"> 
      <slot></slot> 
     </div> 
    </div> 
</template> 
<script type="text/babel"> 
    export default { 
     props: { 
      title: String 
      // expanded: { 
      //  type: Boolean, 
      //  default: true 
      // } 
     }, 
     data: function() { 
      return { 
       expanded: true 
      } 
     }, 
     methods: { 
      toggleExpand: function() { 
       this.expanded = !this.expanded; 
       this.$emit('expand'); 
      } 
     } 
    } 
</script> 

そして、私のHTMLファイル

<expandable-panel> 
    <expandable-item title='title 1'>Lorem ipsum...</expandable-item> 
    <expandable-item title='title 2'>Lorem ipsum...</expandable-item> 
    <expandable-item title='title 3'>Lorem ipsum...</expandable-item> 
</expandable-panel> 

マイアプリおよびコンポーネントは、このように登録されています

Vue.component('expandable-panel', require('./components/global/ExpandablePanel.vue')); 
Vue.component('expandable-item', require('./components/global/ExpandableItem.vue')); 
const app = new Vue({ 
    el: '#app' 
}); 

問題: $emit部分は、親コンポーネント内@expanded="doStuff"に到達していないようです。 それが届いても、どうすればexpandedの値を正しく切り替えることができますか?これに小道具を使うことはできますか?

今は各要素を切り替えますが、他の要素は更新できません。 はExpandablePanelコンポーネントでは、あなたに

+1

はい、あなたは小道具を介してそれを制御することもできますし、この目的のために[vuex](https://vuex.vuejs.org/ja/)のような状態管理を探ることもできます。 – Saurabh

答えて

1

あなたが発することができるので、:それはあなたが子供から発光しているものであるとして、あなただけ@expandを持っている必要があります$ parentオブジェクト経由のイベント。

まず、親オブジェクトの作成時に、this.$onとあなたのイベントをリッスン:

あなたの子コンポーネントの内部次に
Vue.component('parent', { 
    template: `<div><slot></slot></div>`, 
    created: function() { 
    this.$on('event', function(message) { 
     alert(message); 
    }) 
    } 
}); 

はここ$parent.$emit

Vue.component('child', { 
    template: `<button @click="$parent.$emit('event', 'From child')">I'm slot</button>` 
}); 

でこのイベントを発する取り組んでいるデモ:https://jsfiddle.net/rdjjpc7a/1754/

+0

ありがとうございます。それはこのように動作します。 –

0

をありがとう:あなたはここで、親と子の間の厳密な関係を持っている

<template> 
    <div class="expandable-panel" @expand="doStuff"> 
     <slot></slot> 
    </div> 
</template> 
+0

ご返信ありがとうございます。一つの質問があります。 'doStuff'メソッドを' ExpandablePanel'の内部に置くべきでない場合は、どこで定義しますか? –

+0

@NightFallあなたのアプリをどのように構造化するかによって、親は子が拡張されているかどうかを知っている必要がありますか? – Saurabh

関連する問題