Vue.js 中相互依赖的属性
Interdependent properties in Vue.js
我在 Vue.js 中遇到了一个相互依赖属性的案例,我想知道是否有更聪明的方法来设置它。它是一种通过设置开始时间 (A) and/or 结束时间 (B) and/or 持续时间 (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
,则 Diff 设置 A
- 差异可以是唯一填写的字段
思路是:通过改变A来移动span,expand/contract通过改变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);
}
}
}
}
});
您可以将 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
}
}
}
});
我在 Vue.js 中遇到了一个相互依赖属性的案例,我想知道是否有更聪明的方法来设置它。它是一种通过设置开始时间 (A) and/or 结束时间 (B) and/or 持续时间 (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 ,则 Diff 设置 A
- 差异可以是唯一填写的字段
思路是:通过改变A来移动span,expand/contract通过改变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);
}
}
}
}
});
您可以将 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
}
}
}
});