【问题标题】:vuejs: Update computed property when nested data changesvuejs:嵌套数据更改时更新计算属性
【发布时间】:2020-09-09 15:37:09
【问题描述】:

我有一个计算属性,它依赖于数据对象更新来执行计算并返回值。每当更新第一级嵌套时,计算属性就会更新,但是当基础对象的嵌套数据 props 更新时,计算属性不会更新。

我在下面提供了代码示例。本质上,当this.form.business_details.usage 的嵌套属性更新时,就会出现问题。详细地说,当this.form.business_details.quote_type 更新时,this.completion.business_details.quote_type 也会更新,因为后者依赖于前者。

但是,当 this.form.business_details.usage.spend_type 更新时,completion() 的计算属性不会重新评估。计算属性是否默认不监视嵌套数据?如果没有,如何触发更新?

<script>
import Form from '@/classes/Form';
import { filter, map, snakeCase } from 'lodash';

export default {
  name: 'Form',

  computed: {
    completion() {
      return {
        business_details: {
          postcode: this.generateFormCompletionObject(true, this.form.business_details.postcode),
          quote_type: this.generateFormCompletionObject(true, this.form.business_details.quote_type),
          current_supplier: this.generateFormCompletionObject(true, this.form.business_details.current_supplier),
          knows_usage: this.generateFormCompletionObject(true, this.form.business_details.knows_usage, true),
          usage: {
            spend_type: this.generateFormCompletionObject(
              typeof this.form.business_details.knows_usage === 'boolean' && this.form.business_details.knows_usage,
              typeof this.form.business_details.knows_usage === 'boolean' && this.form.business_details.spend_type
            ),
            billing_period: this.generateFormCompletionObject(
              typeof this.form.business_details.knows_usage === 'boolean' && this.form.business_details.knows_usage,
              typeof this.form.business_details.knows_usage === 'boolean' && this.form.business_details.billing_period
            ),
            amount: this.generateFormCompletionObject(
              typeof this.form.business_details.knows_usage === 'boolean' && this.form.business_details.knows_usage,
              typeof this.form.business_details.knows_usage === 'boolean' && this.form.business_details.amount
            ),
          },
        },
      };
    },

    completionPercentage() {      
      const required = this.recursiveCompletionCheck(Object.values(this.completion.business_details))
        .flat()
        .filter(value => value)
        .map(value => +!! value.given);

      return required.filter(value => value).length / required.length * 100;
    },
  },

  data() {
    return {
      completed: {
        business_details: false,
        personal_details: false,
      },
      form: new Form({
        business_details: {
          postcode: new URLSearchParams(window.location.search).get('postcode') || null,
          quote_type: null,
          current_supplier: null,
          knows_usage: null,
          usage: {
            spend_type: null,
            billing_period: null,
            amount: null,
          },
        },
        personal_details: {
          full_name: null,
          email: null,
          phone: null,
          email_consent: false,
        },
      }),
    };
  },

  methods: {
    generateFormCompletionObject(required, key, requiresBoolean = false) {
      return {
        required: required,
        given: requiresBoolean
          ? typeof key === 'boolean' 
          : !! key,
      };    
    },

    recursiveCompletionCheck(values) {
      return values.map(value => {
        if ('required' in value && value.required) return value;
        if ('required' in value && !value.required) return null;

        if (!! Object.keys(value).length) {
          return recursiveCompletionChecker(Object.values(value));
        }

        return null;
      });
    },
  },
}
</script>

【问题讨论】:

    标签: javascript vue.js


    【解决方案1】:

    嵌套对象属性不会自动重新评估。您可以通过watch 观察它的变化。 Here is the documentation for more info。您需要的相关部分是:

    var vm = new Vue({
      el: '#app',
      computed: {
        foo() { return this.item.foo; }
      },
      watch: {
        foo() { console.log('Foo Changed!'); }
      },
      data: {
        item: { foo: 'foo' }
      }
    })
    

    【讨论】:

    • codepen.io/threenuc/pen/XWgXBRv 我认为这个答案是不正确的。 Vue 提到的反应性警告只是 - 添加一个不存在的新对象属性并通过数组索引更新某些内容。您提供的链接未提及任何嵌套警告
    猜你喜欢
    • 2018-01-02
    • 2019-12-05
    • 1970-01-01
    • 1970-01-01
    • 2019-05-18
    • 2019-06-06
    • 2019-07-14
    • 2018-12-11
    • 1970-01-01
    相关资源
    最近更新 更多