【问题标题】:Vue.js - Computed property not updating - child componentVue.js - 计算属性未更新 - 子组件
【发布时间】:2018-12-03 13:09:57
【问题描述】:

我创建了一个名为 DefaultButton 的简单组件。 它基于创建此组件时正在设置的属性。 关键是安装后,它不会对与“defaultbutton”相关的更改做出反应,即位于属性中的对象

<template>
  <button :class="buttonClass" v-if="isActive" @click="$emit('buttonAction', defaultbutton.id)" >
    {{ this.defaultbutton.text }} 
  </button>
  <button :class="buttonClass" v-else disabled="disabled">
    {{ this.defaultbutton.text }} 
  </button>
</template>


<script>
export default {
  name: "defaultbutton",
  props: {
    defaultbutton: Object
  },
  computed: {
    buttonClass() {
      return `b41ngt ${this.defaultbutton.state}`;
    },
    isActive() {
      return (this.defaultbutton.state === "BUTTON_ACTIVE" || this.defaultbutton.state === "BUTTON_ACTIVE_NOT_CHOSEN");
    }
  }
};
</script>

有以下组件作为父组件:

<template>
    <div v-if="state_items.length == 2" class="ui placeholder segment">
        {{ this.state_items[0].state }}
        {{ this.state_items[1].state }}
        {{ this.current_active_state }}
      <div class="ui two column very relaxed stackable grid">
        <div class="column">
            <default-button :defaultbutton="state_items[0]" @buttonAction="changecurrentstate(0)"/>
        </div>
        <div class="middle aligned column">
            <default-button :defaultbutton="state_items[1]" @buttonAction="changecurrentstate(1)"/>
        </div>
      </div>
      <div class="ui vertical divider">
        Or
      </div>
    </div>

</template>


<script type="text/javascript">
    import DefaultButton from '../Button/DefaultButton'

    export default {
        name: 'changestatebox',
        data() {
            return {
                current_active_state: 1
            }
        },
        props: {
            state_items: []
        },
        components: {
            DefaultButton
        },
        methods: {
            changecurrentstate: function(index) {
                if(this.current_active_state != index) {
                    this.state_items[this.current_active_state].state = 'BUTTON_ACTIVE_NOT_CHOSEN';
                    this.state_items[index].state = 'BUTTON_ACTIVE';
                    this.current_active_state = index;
                }
            },
        },
        mounted: function () {
            this.state_items[0].state = 'BUTTON_ACTIVE';
            this.state_items[1].state = 'BUTTON_ACTIVE_NOT_CHOSEN';
        }
    }

</script>

它清楚地显示,使用:

{{ this.state_items[0].state }}
{{ this.state_items[1].state }}
{{ this.current_active_state }}

这些项目的状态正在更改,但我无法在生成的“DefaultButtons”上看到任何结果。这些组件中包含的对象类不会更改。

@编辑

我完全改变了传递数据的方式。 由于这个变化,我放弃了数组的使用;相反,我使用了两个完全不相关的对象。 结果是一样的 - 子组件的对象的类不是

默认按钮.vue:

<template>
  <button :class="buttonClass" v-if="isActive" @click="$emit('buttonAction', defaultbutton.id)" >
    {{ this.defaultbutton.text }} 
  </button>
  <button :class="buttonClass" v-else disabled="disabled">
    {{ this.defaultbutton.text }} 
  </button>
</template>

<style lang="scss">
  import './DefaultButton.css';
</style>

<script>
export default {
  name: "defaultbutton",
  props: {
    defaultbutton: {
      type: Object,
      default: () => ({
        id: '',
        text: '',
        state: '',
      })
    }
  },
  computed: {
    buttonClass() {
      return `b41ngt ${this.defaultbutton.state}`;
    },
    isActive() {
      return (this.defaultbutton.state === "BUTTON_ACTIVE" ||
        this.defaultbutton.state === "BUTTON_ACTIVE_NOT_CHOSEN");
    }
  }
};
</script>

ChangeStateBox.vue:

<template>
    <div class="ui placeholder segment">
        {{ this.state_first.state }}
        {{ this.state_second.state }}
        {{ this.current_active_state }}
      <div class="ui two column very relaxed stackable grid">
        <div class="column">
            <default-button :defaultbutton="state_first" @buttonAction="changecurrentstate(0)"/>
        </div>
        <div class="middle aligned column">
            <default-button :defaultbutton="state_second" @buttonAction="changecurrentstate(1)"/>
        </div>
      </div>
      <div class="ui vertical divider">
        Or
      </div>
    </div>

</template>

<script type="text/javascript">
    import DefaultButton from '../Button/DefaultButton'

    export default {
        name: 'changestatebox',
        data() {
            return {
                current_active_state: 1
            }
        },
        props: {
            state_first: {
                type: Object,
                default: () => ({
                  id: '',
                  text: ''  
                })
            },
            state_second: {
                type: Object,
                default: () => ({
                  id: '',
                  text: ''  
                })
            },
        },
        components: {
            DefaultButton
        },
        methods: {
            changecurrentstate: function(index) {
                if(this.current_active_state != index) {
                    if(this.current_active_state == 1){

                        this.$set(this.state_first, 'state', "BUTTON_ACTIVE_NOT_CHOSEN");
                        this.$set(this.state_second, 'state', "BUTTON_ACTIVE");

                    } else {

                        this.$set(this.state_first, 'state', "BUTTON_ACTIVE");
                        this.$set(this.state_second, 'state', "BUTTON_ACTIVE_NOT_CHOSEN");

                    }
                    this.current_active_state = index;
                }
            },
        },
        created: function () {
            this.state_first.state = 'BUTTON_ACTIVE';
            this.state_second.state = 'BUTTON_ACTIVE_NOT_CHOSEN';
        }
    }
</script>

【问题讨论】:

  • 您已声明您的道具错误。 defaultbutton 应该是一个对象,required 应该是该对象中的一个条目。
  • 好吧,我现在已经改变了它,required 不再存在,但结果是一样的 - 似乎默认按钮的工作方式就像没有引用父级的数据

标签: javascript vue.js


【解决方案1】:

您的主要问题是您更改按钮状态的方式,根据Array change detection vue 无法通过索引检测突变。

由于 JavaScript 的限制,Vue 无法检测到以下内容 更改为数组:

当您直接使用索引设置项目时,例如 vm.items[indexOfItem] = newValue修改长度时 数组,例如vm.items.length = newLength

【讨论】:

    【解决方案2】:

    You're declaring props wrong。它要么是一组 prop 名称,要么是一个对象,每个 prop 都有一个条目来声明其类型,或者它是一个对象,每个 prop 都有一个条目,声明多个属性。

    你有

        props: {
            state_items: []
        },
    

    但是对于supply a default应该是

        props: {
            state_items: {
                type: Array,
                default: []
            }
        },
    

    但是您的问题很可能是您正在以 Vue can't react to the change 的方式变异 state_items

    【讨论】:

      【解决方案3】:

      如果有人遇到同样的问题:

      @Roy J 和 @DobleL 是对的。

      此问题背后的原因与状态对象的错误初始化有关。

      根据文档:

      Vue cannot detect property addition or deletion. 
      Since Vue performs the getter/setter conversion process during instance
      initialization, a property must be present in the 
      data object in order for Vue to convert it and make it reactive. 
      

      在阅读这句话之前,我曾经以以下对象作为初始数据:

      var local_state_first = {
        id: '1',
        text: 'Realized',
      };
      
      var local_state_second = {
          id: '2',
          text: 'Active'  
      };
      

      它的正确版本如下所示:

      var local_state_first = {
        id: '1',
        text: 'Realized',
        state: 'BUTTON_ACTIVE'
      };
      
      var local_state_second = {
        id: '2',
        text: 'Active',
        state: 'BUTTON_ACTIVE'
      };
      

      而将主要组件声明为:

      <change-state-box :state_first="local_state_first" :state_second="local_state_second" @buttonAction="onbuttonAction"/>
      

      其余代码保持不变(查看我主帖中的@edit 标记)

      【讨论】:

        猜你喜欢
        • 2017-07-29
        • 2019-06-18
        • 2018-07-11
        • 2016-04-04
        • 1970-01-01
        • 2019-10-05
        • 2019-04-18
        • 2018-01-25
        相关资源
        最近更新 更多