【问题标题】:Interdependent properties in Vue.jsVue.js 中的相互依赖属性
【发布时间】:2016-04-13 15:39:43
【问题描述】:

我有一个 Vue.js 中相互依赖的属性的案例,我想知道是否有更聪明的方法来设置它。这是一种通过设置开始时间 (A) 和/或结束时间 (B) 和/或持续时间 (Diff) 来定义时间跨度的形式——这里用整数简化。根据哪个属性更改,其他属性将相应计算。如果我没有忘记什么,规则如下:

  • 如果设置了 Diff,A 会更改 B
  • 如果设置了 B 并且 A 具有先前的值,则 A 会更改 B 和 Diff
  • 如果设置了 B 并且 A 没有以前的值,则 A 会更改 Diff
  • 如果设置了 A,B 会更改 Diff
  • 如果 A 未设置但 Diff 和 B 具有先前的值,则 B 会更改 Diff
  • 如果 A 未设置但 Diff 和 B 没有先前的值,则 B 设置 A
  • 如果设置了 A,则 Diff 会更改 B
  • 如果 A 未设置但 B 设置,则差异设置 A
  • Diff 可以是唯一填写的字段

想法是:通过改变A来移动span,通过改变B或Diff来扩大/收缩span。根据逻辑计算缺失值。

我有一个使用 $watch 的工作脚本:https://jsbin.com/korole/edit?html,js,output

同样,有没有更聪明的方法来设置它?非常感谢您的帮助!

var vm = new Vue({

    el: '#calculate-difference',

    data: {
        a: '',
        b: '',
        diff: ''
    },

    methods: {
        updateProperty: function(prop, val) {
            if (parseInt(this[prop]) !== val) this[prop] = val;
        }
    },

    watch: {

        'a': function(val, old) {
            var newB, newDiff;

            if (val === '') return;

            // A changes B if Diff is set
            if (this.diff !== '') {
                newB = parseInt(val) + parseInt(this.diff);
                this.updateProperty('b', newB);
            }

            // A changes B and Diff if B is set and A had previous value
            else if (old !== '' && this.b !== '') {
                newB = parseInt(this.b) + (parseInt(val) - parseInt(old));
                this.updateProperty('b', newB);
                newDiff = parseInt(this.b) - parseInt(val);
                this.updateProperty('diff', newDiff);
            }

            // A changes Diff if B is set and A didn't have previous value
            else if (this.b !== '') {
                newDiff = parseInt(this.b) - parseInt(val);
                this.updateProperty('diff', newDiff);
            }
        },

        'b': function(val, old) {
            var newDiff;

            if (val === '') return;

            // B changes Diff if A is set
            if (this.a !== '') {
                newDiff = parseInt(val) - parseInt(this.a);
                this.updateProperty('diff', newDiff);
            }

            // B changes Diff if A is not set but Diff and B had previous value
            else if (old !== '' && this.diff !== '') {
                newDiff = parseInt(this.diff) + (parseInt(val) - parseInt(old));
                this.updateProperty('diff', newDiff);
            }

            // B sets A if A is not set but Diff and B didn't have previous value
            else if (this.diff !== '') {
                newA = parseInt(val) - parseInt(this.diff);
                this.updateProperty('a', newA);
            }
        },

        'diff': function(val) {
            var newB, newA;

            if (val === '') return;

            // Diff changes B if A is set
            if (this.a !== '') {
                newB = parseInt(this.a) + parseInt(val);
                this.updateProperty('b', newB);
            }

            // Diff sets A if A is not set but B
            else if (this.b !== '') {
                newA = parseInt(this.b) - parseInt(val);
                this.updateProperty('a', newA);
            }
        }

    }

});

编辑:是的,有一个更聪明的方法。

谢谢你,杰夫!避免使用$watch,使用Computed Properties。代码更干净,更容易掌握。 A 改变 B,B 改变 A。差值被计算出来。

使用计算属性的改进脚本:https://jsbin.com/jixili/edit?html,js,output

var vm = new Vue({

    el: '#calculate-difference',

    data: {
        store: {
            a: '',
            b: '',
            diff: ''
        }
    },

    computed: {
        a: {
            get: function() {
                return this.store.a;
            },
            set: function(val) {
                var old = this.store.a;
                this.store.a = val;

                if (this.diff === '') return;

                if (val === '' && this.b !== '') {
                    this.b = '';
                }

                if (val !== '' && this.b === '') {
                    this.b = parseInt(val) + parseInt(this.diff);
                }

                if (val !== '' && this.b !== '' && old !== '') {
                    this.b = parseInt(this.a) + (parseInt(this.b) - parseInt(old));
                }
            }
        },
        b: {
            get: function() {
                return this.store.b;
            },
            set: function(val) {
                this.store.b = val;

                if (this.diff === '') return;

                if (val === '' && this.a !== '') {
                    this.a = '';
                }

                if (val !== '' && this.a === '') {
                    this.a = parseInt(val) - parseInt(this.diff);
                }
            }
        },
        diff: {
            get: function() {
                if (this.a !== '' && this.b !== '') {
                    this.store.diff = parseInt(this.b) - parseInt(this.a);
                }

                return this.store.diff;
            },
            set: function(val) {
                this.store.diff = val;

                if (val === '') return;

                if (this.a !== '') {
                    this.b = parseInt(this.a) + parseInt(val);
                }

                if (this.a === '' && this.b !== '') {
                    this.a = parseInt(this.b) - parseInt(val);
                }
            }
        }
    }
});

【问题讨论】:

    标签: javascript properties dependencies vue.js


    【解决方案1】:

    您可以将diff 设为计算属性并使用getter 和setter 函数,这样您也可以更新差异。查看http://vuejs.org/guide/computed.html#Computed_Setter。这适用于v-model,因此它会自动显示 diff 的值,并在您更改时调用set

    根据您的评论进行编辑,您可以创建一个属性来保存 diff 的值,然后根据您的应用逻辑仅设置 A 或 B

    var vm = new Vue({
    
      el: '#calculate-difference',
    
      data: {
        a: '',
        b: '',
        diffValue:''
      },
      computed:{
        diff:{
          get:function() {
            return parseInt(this.b) - parseInt(this.a);
          },
          set:function(newDiff){
            //Store the value of the diff input
            diffValue = newDiff;
    
            //Update A and B based on new difference, only if needed
          }
        }
      }
    });
    

    【讨论】:

    • 感谢您的回答!我想我没有很好地澄清,即使只是一个持续时间也可以在表格中完成,所以我不能(总是)计算这个值。它是一种跟踪活动的表单,我不想强​​迫用户提供特定的开始和结束时间。也许我所拥有的已经是在这种情况下如何完成的?
    • @M165437 这个编辑有帮助吗?我认为将diff 设为计算属性对您的应用最有意义。因为它是两个静态值之间的差异,所以才有意义。您可能必须执行某种类型的解决方法,例如上面的编辑以使其适合,但如果您可以使其正常工作,这将少得多的代码。
    猜你喜欢
    • 1970-01-01
    • 2013-07-19
    • 2013-08-04
    • 2020-08-31
    • 1970-01-01
    • 1970-01-01
    • 2015-07-08
    • 2018-08-11
    • 2017-11-29
    相关资源
    最近更新 更多