首页 文章

Vue.js:根据子组件的状态禁用父组件上的按钮

提问于
浏览
1

我已阅读有关父母和子女沟通的文件 . 我知道孩子们通过发送事件与父母沟通,而父组件将道具传递给子组件 .

我正在努力将这个原则应用到我的项目中:

我有一个包含多个页面的 Survey 组件 . 我正在使用vswipe为页面实现滑块(https://github.com/wangdahoo/vswipe)每个 <swipe-item> 包含一个 QuestionGroup 组件,而该组件又包含多个 Questions .

其中一些问题是必需的 .

如何根据当前显示的 QuestionGroup 组件中 questions 的状态禁用/启用vswipe下一个和上一个按钮(包含在父 Survey 组件中)?

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

相关问题