2017-06-13 289 views
1

我已閱讀有關父和子通信的文檔。我明白,孩子們通過發佈事件與父母溝通,並且父母組件將道具傳遞給子組件。Vue.js:根據子組件的狀態禁用父組件上的按鈕

我奮力這個原則適用於我的項目:

我有一個包含多個頁面的Survey組件。我正在使用vswipe實現頁面的滑塊(https://github.com/wangdahoo/vswipe) 每個<swipe-item>包含一個QuestionGroup組件,該組件又包含多個Questions

其中一些問題是必需的。

如何基於當前顯示的QuestionGroup組件中的questions的狀態禁用/啓用vswipe下一個和上一個按鈕(包含在父組件Survey中)?

回答

0

這可能有點痛苦。您可以考慮使用VueX以獲得更優雅的圖案。

順便說一句,你說的一切都在你的問題。只需使用事件從小孩到父母溝通。

這裏有一種方法:

Vue.component('Question', { 
 
    template: `<div> 
 
     {{ name }}: 
 
     <input type="text" 
 
      @input="toogleFilled($event.target.value)"> 
 
     </input> 
 
    </div>`, 
 
    props: ['name'], 
 
    methods: { 
 
    toogleFilled(inputValue) { 
 
     // Emit name of the component and true if input is filled... 
 
     this.$emit('filled', this.name, !!inputValue.length); 
 
    } 
 
    } 
 
}); 
 

 
Vue.component('QuestionGroup', { 
 
    template: `<div> 
 
     <template v-for="(q, key) in questions"> 
 
      <question :name="key" @filled="toogleReady"> 
 
      </question> 
 
     </template> 
 
    </div>`, 
 
    data() { 
 
    return { 
 
     // Each key will be the name of the question 
 
     // Each value will be if it's filled or not 
 
     questions: { 
 
     'Question1': false, 
 
     'Question2': false 
 
     } 
 
    }; 
 
    }, 
 
    methods: { 
 
    toogleReady(name, filled) { 
 
     this.questions[name] = filled; 
 

 
     // Check if each question is filled, if yes, emit true 
 
     if (filled && Object.values(this.questions).every(q => q)) { 
 
     this.$emit('readyToSwipe', true); 
 
     } else { 
 
     this.$emit('readyToSwipe', false); 
 
     } 
 
    } 
 
    } 
 
}); 
 

 
Vue.component('Survey', { 
 
    template: `<div> 
 
    \t <button :disabled="isDisabled">I'm doing nothing</button> 
 
     <question-group @readyToSwipe="toogleDisabled"></question-group> 
 
    </div>`, 
 
    data() { 
 
    return { 
 
     isDisabled: true 
 
    }; 
 
    }, 
 
    methods: { 
 
    toogleDisabled(ready) { 
 
     // Disable the button if the question-group is not ready 
 
     this.isDisabled = !ready; 
 
    } 
 
    } 
 
}); 
 

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

 
<div id="app"> 
 
    <survey></survey> 
 
</div>