Vue.js: отключение кнопки на родительском компоненте в зависимости от состояния дочернего компонента

1

Я прочитал документацию по связи с родителями и детьми. Я понимаю, что дети сообщают родителям, испуская события и что родительский компонент передает реквизиты дочернему компоненту.

Я изо всех сил пытаюсь применить этот принцип к моему проекту:

У меня есть компонент Survey который содержит несколько страниц. Я использую vswipe для реализации слайдера для страниц (https://github.com/wangdahoo/vswipe). Каждый <swipe-item> содержит компонент QuestionGroup который, в свою очередь, содержит несколько Questions.

Некоторые из этих вопросов требуются.

Как отключить/включить следующие и предыдущие кнопки vswipe (которые содержатся в родительском компоненте Survey) в зависимости от состояния questions в отображаемом в данный момент компоненте QuestionGroup?

Теги:
vue.js
vuejs2

1 ответ

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 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>
    	<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>

Ещё вопросы

Сообщество Overcoder
Наверх
Меню