2017-06-13 3 views
1

Ich habe die Dokumentation zur Eltern- und Kindkommunikation gelesen. Ich verstehe, dass Kinder mit dem Elternteil kommunizieren, indem sie Ereignisse aussenden und dass die Elternkomponente Requisiten an die Kindkomponente weiterleitet.Vue.js: Deaktivieren einer Schaltfläche für die übergeordnete Komponente basierend auf dem Status der untergeordneten Komponente

Ich kämpfe dieses Prinzip auf mein Projekt anzuwenden:

Ich habe eine Survey Komponente, die mehrere Seiten enthält. Ich benutze vswipe, um einen Schieberegler für die Seiten zu implementieren (https://github.com/wangdahoo/vswipe) Jede <swipe-item> enthält eine QuestionGroup Komponente, die wiederum mehrere Questions enthält.

Einige dieser Fragen sind erforderlich.

Wie deaktiviere ich/aktivieren Sie die vswipe nächste und vorherige Tasten (die in der übergeordneten Survey Komponente enthalten sind), basierend auf dem Zustand der questions in der aktuell angezeigten QuestionGroup Komponente?

Antwort

0

Es kann ein bisschen schmerzhaft sein. Sie können die Verwendung von VueX für ein eleganteres Muster in Erwägung ziehen.

Übrigens, Sie haben alles in Ihrer Frage gesagt. Verwenden Sie einfach Ereignisse, um von einem Kind zum anderen zu kommunizieren. Hier

ist ein Weg:

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>

Verwandte Themen