计算属性相互依赖,在 Vue 1 和 2 上具有不同的行为

Posted

技术标签:

【中文标题】计算属性相互依赖,在 Vue 1 和 2 上具有不同的行为【英文标题】:Computed properties depending on each other with different behaviors on Vue 1 and 2 【发布时间】:2020-09-15 03:23:00 【问题描述】:

我遇到了一个问题,我有一个带有格式化数字的输入框,每个输入框都包含一个计算属性。当我更改输入时,Vue 会自动重新计算数字,我将无法准确输入我需要的内容。这只发生在 Vue 2 中。

new Vue(
  el: '#vue-app',

  data: function() 
    return 
      direction: 'hi',
      target: 49.99,
      maxRoll: Big(99.99),
      oddsDividend: Big(100),
    
  ,
  watch: 
    direction: function() 
      this.target = this.maxRoll.minus(this.target).abs()
    
  ,
  computed: 
    chance: 
      get: function() 
        return this.direction === 'hi' ?
          this.maxRoll.minus(this.target).toFixed(2) :
          Big(this.target).toFixed(2)
      ,
      set: function(newValue) 
        this.target = this.direction === 'hi' ?
          this.maxRoll.minus(newValue).toFixed(2) :
          Big(newValue).toFixed(2)
      
    ,
    odds: 
      get: function() 
        return this.direction === 'hi' ?
          this.oddsDividend.div(this.maxRoll.minus(this.target)).toFixed(4) :
          this.oddsDividend.div(this.target).toFixed(4)
      ,
      set: function(newValue) 
        this.target = this.direction === 'hi' ?
          this.oddsDividend.div(newValue).minus(this.maxRoll).abs().toFixed(2) :
          this.oddsDividend.div(newValue).toFixed(2)
      
    ,
  
);

例如,这里有一个 Vue 2 的小提琴:https://jsfiddle.net/fc4b60n3/ 尝试在第二个输入框中键入数字 234 或任何其他数字。它只会捕获第一个数字并以此执行所有计算。

现在使用 Vue 1:https://jsfiddle.net/fc4b60n3/1/ 在这里您可以输入完整的数字,例如234 并且只有当您失去输入焦点时,它才会重新计算自己的计算属性。这是我想要的行为,但我必须使用 Vue 1,它与我当前的设置不兼容。

所以我的问题是。这些 Vue 版本之间发生了什么变化导致了这种情况?如何使用 Vue 2 让代码像我想要的那样工作?

编辑论坛帖子,以保持一切同步:https://forum.vuejs.org/t/96370

【问题讨论】:

【参考方案1】:

我认为 v-model 在 v1 上使用 onchange 事件(等到失去焦点然后改变) 在 v2 上,它使用 oninput 事件(只要你输入一个新行)

所以要修复您的代码,请使用v-bind:valueonChange event 来设置该值而不是v-model

【讨论】:

但是,如果您查看 v1 Fiddle,它仍然在我键入时进行计算。 我已将 v-model="odds" 替换为 v-bind:value="odds" v-on:change="odds= $event.target.value",它会等到失去焦点,但不会像 Vue 1 那样更新其他字段。 你可以通过使用 v-model="odds" 来解决这个问题,从计算的赔率中删除 toFixed(4) (添加那些 .000 的部分),创建一个新方法 formatodds 来添加那些 toFixed (4) , 添加:change='formatodds' , 所以现在你可以正常计算但只有当你失去焦点时值才会改变 不幸的是,这仍然行不通,因为即使没有小数点,它仍然会重新计算,例如,如果您输入 234,它将重新计算为 232。这里的真正问题是输入被独占锁定为用户集中注意力。我不知道 Vue 1 如何或为什么这样做,但 Vue 2 没有。我现在已经决定使用惰性修饰符v-model.lazy="odds",但这不是我想要的生产方式。 所以如果我想输入 2345 我不能,因为它会在我输入 5 之前重新计算并用 232 替换我的输入。

以上是关于计算属性相互依赖,在 Vue 1 和 2 上具有不同的行为的主要内容,如果未能解决你的问题,请参考以下文章

1 vue 关键字解释

Vue中的计算属性与监视属性

Vue computed计算属性 理解

Vue computed和watch的区别

Vue computed和watch的区别

Vue 3:计算属性不跟踪其在组合 API 中的依赖关系