Vue.js中的相互依赖属性

Interdependent properties in Vue.js

本文关键字:依赖 属性 js Vue      更新时间:2023-09-26

我在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,则差异更改B
  • 如果未设置A但设置B,则Diff设置A
  • Diff可以是唯一填写的字段

其思想是:通过更改A来移动跨度,通过更改B或Diff来扩展/收缩跨度。根据逻辑计算缺失值。

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

再说一遍,有没有更聪明的方法来设置这个?非常感谢您的帮助!

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,使用计算属性。代码更干净,更容易掌握。A改变B,B改变A。计算差值。

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

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);
                }
            }
        }
    }
});

您可以将diff作为一个计算属性,并使用getter和setter函数,这样您也可以更新diff。退房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
      }
    }
  }
});