【问题标题】:Preventing Vue from looping防止 Vue 循环
【发布时间】:2018-03-15 06:46:42
【问题描述】:

我有三个字段

小时 -- 分钟 -- 和总计

如果小时或分钟发生变化,我想计算一个总数。 如果总数发生变化,我想计算相应的分钟和小时。

例子:

1 小时 30 分钟 = 1.5 总时间

2.25 总 = 2 小时 15 分钟

我正在尝试通过手表来实现这一目标

watch: {
            hour: {
                handler: (new_hour, old_hour) => {
                    if(isNaN(new_hour)){
                        manual.hour = old_hour
                    }else{
                        manual.setTotal();
                    }
                }
            },
            minutes: {
                handler: (new_minutes, old_minutes) => {
                    if(isNaN(new_minutes)){
                        manual.minutes = old_minutes
                    }else{
                        if(Number(new_minutes) > 60){
                            manual.minutes = old_minutes
                        }else{
                            manual.setTotal();
                        }
                    }
                }
            },
            total:{
                handler: (new_total, old_total) => {
                    if(isNaN(new_total)) {
                        manual.total = old_total;
                    }else{
                        const hour = new_total.split(",")[0];
                        const minutes = new_total.split(",")[1];
                        manual.hour = hour;
                        manual.minutes = (minutes * 60).toFixed(0);
                    }
                }
            }
        }

但是这会导致循环,因为 on 处理程序总是调用另一个处理程序。如何以更智能的方式做到这一点?

【问题讨论】:

    标签: java vue.js vuejs2


    【解决方案1】:

    您可以使用 onkeyup 监听器(和/或更改)

    new Vue({
    	el: "#app",
      data: {
      	input_h: 0,
      	input_m: 0,
      	input_t: 0
      },
      methods: {
      update_h (e) {
      	this.input_h = Number(e.target.value)
        this.update_t(null)
      },
      update_m (e) {
      	this.input_m = Number(e.target.value)
        this.update_t(null)
      },
      update_t (e) {
      	if (e === null) {
        	this.input_t = Math.round((this.input_h + this.input_m / 60) * 100)/100
        } else {
        	this.input_t = Number(e.target.value)
          this.input_h = Math.floor(this.input_t)
          this.input_m = Math.round(this.input_t%1 * 60)
        }
        
      },
      }
    })
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.4/vue.js"></script>
    <div id="app">
      <input :value="input_h" @keyUp="update_h"/>Hours<br/>
      <input :value="input_m" @keyUp="update_m"/>Minutes<br/>
      <input :value="input_t" @keyUp="update_t"/>Total<br/>
    </div>

    否则,如果要防止循环依赖,则需要设置单一数据源,并使用计算的 getter 和 setter 来更新其他字段。您甚至不必为此使用可见字段。 https://jsbin.com/tagupab/edit 有一个工作示例

    【讨论】:

      【解决方案2】:

      我还没有检查过这个,但也许你可以用 setter 交换观察者的计算属性,参见 ref Computed setter

      注意这里的评论circular dependency on observed properties #622 (yyx990803 commented on Dec 11, 2014)

      问题是即使存在循环依赖,最终 值应该能够在 1 次额外迭代后稳定(其中 然后 Vue 将停止,因为新的评估值相同)

      我猜你可以放

      if (newValue === oldValue) {
        return
      }
      

      在每个观察者的顶部。无论如何,这就是计算所做的。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-09-01
        • 2015-07-30
        • 1970-01-01
        • 1970-01-01
        • 2016-11-05
        • 2011-12-08
        • 2012-05-08
        • 1970-01-01
        相关资源
        最近更新 更多