2017-06-13 290 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>