【问题标题】:Vue reactivity: Computed changes data but then is not reacting to itVue 反应性:计算的更改数据但没有对其做出反应
【发布时间】:2018-12-23 03:16:51
【问题描述】:

我有一个简单的设置。 “计算”用于检索数据。在一个简单的条件下,有时应该更改数据。然后我希望,数据的变化会再次触发“计算”。但这种情况并非如此。我当前的解决方案是 setTimeout,因为这会再次触发“计算”。

这里是codepen链接:https://codepen.io/MH88/pen/oMbBzZ?editors=1011

这里是代码-sn-p。

//HTML Output
<div id="app" class="l-container l-vPad--mid">
  <h1>This should return 4</h1>
    <h2>getNumber: {{getNumber}}</h2>   
</div>

//Javascript logic
new Vue({
el: '#app',
data: {
    number: 5
  },
  computed: {
    getNumber() {
      var x = this.number;
      if(this.number == 5) {

          //Why is this not working?As data changes, the computed should 
          //react to it again, no?
          this.number--;

          //This solution works but there needs to be something more eloquent
          //setTimeout(() => {this.number--}, 0);

      }
      return x
    }
  }
});

期待一些想法。

【问题讨论】:

    标签: javascript vue.js


    【解决方案1】:

    您目前没有按照设计的方式使用计算属性。

    在 vue 中,我们有 data 来定义初始数据。如果你这样定义数据:

    data() {
      return {
        number: 5
      }
    }
    

    您可以通过this.number 访问您的号码。您需要将其定义为函数,因为每次创建组件时都需要调用此函数。将其定义为一个函数,可以防止在不同组件之间使用相同的对象引用,从而造成各种麻烦。

    计算属性是基于其他数据计算属性的函数。当它依赖的数据发生变化时,计算属性会自动重新计算。这会自动起作用,但只有在函数没有副作用的情况下。您的计算函数确实有副作用(即它会更改组件上的数据),这会阻止此机制工作。计算属性的一个例子是

    computed: {
      differenceFromHundred() {
        return 100 - this.number;
      },
    
      numberThatCannotBeFive() {
        let x = this.number;
        if (x === 5) {
          return x - 1;
        }
    
        return x;
      }
    }
    

    如果你的函数确实有副作用,你必须使用一个方法。当您调用方法时,它们会返回一个值,就像常规函数一样。

    methods: {
      // This name is misleading. You expect it to just 'get a value', but instead
      // it modifies it sometimes
      getNumber () {
        let x = this.number;
        if(this.number === 5) {
          this.number--;
        }
    
        return this.number
      }
    }
    

    不清楚为什么要修改 number 的值,但请考虑是否可以使用计算属性来获得所需的输出而不更改 number 的值。如果您必须更改该值,请在从生命周期挂钩或显式操作(例如单击或事件)调用的单独函数中进行。您可以在其余代码中使用 this.number,然后按原样使用。

    【讨论】:

    • 我调用了一个单独的方法来更改数据,但由于这是在“计算”属性中调用的,“计算”属性不会再次重新运行。
    • 那是因为在这种情况下你的计算属性仍然有副作用。您的计算属性除了计算之外什么都不做。
    【解决方案2】:

    在 javascript 中,primitive typespassed by value。您将值this.number 保存在变量x 中。这个变量x 是全新的副本。所以改变this.number 并不意味着x 也会改变。所以改变x的值。

    这里是updated codepen

    【讨论】:

    • 谢谢。虽然这可行,但我需要“计算”属性重新开始,因为我的“现实生活”示例基于数据进行了更多计算。我的目标是确保计算的属性再次重新计算。我使用 setTimeout 函数实现了这一点,但希望有另一种解决方案。
    • @betzebube1000 ,计算的属性取决于this.number。只要this.number 的值发生变化,就会调用它。见这个例子pen
    【解决方案3】:

    您正在返回值为“5”的变量“x”,因为您使用“var x = this.number”保存了它。不要返回保存的值 'return x' 而是使用 'return this.number'

    只需将return x 替换为return this.number

    跟随this.number--; 正在减少数字的值,但由于您没有使用数据属性{{number}},因此不会显示。

    看看这个,你就明白了。我希望。 updated code

    计算属性是函数,因此您应该返回更改后的值。 查看文档Computed Properties

    希望对你有帮助。

    【讨论】:

    • 谢谢。这当然可行,但由于我的“现实生活”示例更加复杂,我需要确保“计算”属性基于现在更新的数据属性再次运行。使用 setTimeout,就可以了。但我希望有其他解决方案。
    猜你喜欢
    • 2021-08-14
    • 2018-06-13
    • 2019-11-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-30
    • 1970-01-01
    • 2018-10-11
    相关资源
    最近更新 更多