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

Posted

技术标签:

【中文标题】Vue.js:根据子组件的状态禁用父组件上的按钮【英文标题】:Vue.js: Disabling a button on parent component based on state of child component 【发布时间】:2017-11-15 13:06:15 【问题描述】:

我已阅读有关父母和孩子沟通的文档。我了解子组件通过发出事件与父组件进行通信,并且父组件将道具传递给子组件。

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

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

其中一些问题是必需的。

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

【问题讨论】:

【参考方案1】:

这可能有点痛苦。您可以考虑使用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>

【讨论】:

如果子组件是不可变的(即某种第 3 方 node_module),这将不起作用。

以上是关于Vue.js:根据子组件的状态禁用父组件上的按钮的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Vue.js 中将数据从父组件发送到子组件

Vue.js:子组件改变状态,父组件显示属性未定义

如何在 Vue JS 中将更新的值从父组件发送到子组件?

vue.js 组件传值

根据父状态更新子状态 react 功能组件

在Vue.js中从父组件执行子方法