2017-02-22 78 views
1

我想創建一個使用vue js 2的可擴展項目的列表。這個想法是,當我點擊一個項目時,我希望它展開(顯示它的內容)如果它尚未展開並關閉所有其他展開的元素。我創建了兩個組件expandable-panelexpandable-item。我可以有多種類型的內容,所以我想使用插槽。子組件發射到父母和父母更新所有子組件

的代碼,我有:

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值?我可以使用道具嗎?

現在,它切換每個元素,但我無法更新其他元素。 謝謝

+1

是的,你可以通過道具控制它,或者爲此目的探索一些像[vuex](https://vuex.vuejs.org/en/)這樣的狀態管理。 – Saurabh

回答

1

你這裏有父母和孩子之間嚴格的關係,這樣你就可以發出事件通過$父對象。

首先,父對象創建,傾聽您的活動與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

ExpandablePanel組件:您應該只有@expand因爲這是你從孩子發出什麼:

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

感謝您的回覆。我有一個問題。我應該在哪裏定義'doStuff'方法,如果它不應該在'ExpandablePanel'中? –

+0

@NightFall這取決於你想如何構建你的應用程序,父母是否需要知道孩子是否擴展? – Saurabh