Vue.js:根据子组件

时间:2017-06-13 16:20:29

标签: javascript vue.js vuejs2

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

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

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

其中一些问题是必需的。

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

1 个答案:

答案 0 :(得分: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>