我有一个带有表格行的组件,其中有多个字段。由更新一个字段将使用基于保证金或卖出价格的值更新另一个字段。
但是当我观察所有领域时,我得到了反弹效果。添加_debounce有帮助,但不会解决问题。为了尝试管理问题,我正在使用对观察者的回调来触发 unwatch((,但是当我重新添加观察者时,回调停止取消监视。
我有一个工作要点作为代码示例。
查看示例要点
Vue.component('pricing', {
template: '#pricing-row',
props: ['item'],
mounted() {
this.addWatchers()
},
methods: {
resetWatchers() {
setTimeout(()=> {
this.addWatchers()
}, 700)
},
addWatchers() {
this.updateNet = this.$watch(
function() {
return this.item.net
},
function() {
// unmount other watchers
this.updateMargin()
this.updateSell()
// calculate sell price and update
this.setSellPrice()
// re-add watchers
this.resetWatchers()
}
),
this.updateMargin = this.$watch(
function() {
return this.item.margin
},
function() {
// unmount other watchers which can cause bounce effect
this.updateSell()
// calculate sell price and update
this.setSellPrice()
// re-add watchers
this.resetWatchers()
}
),
this.updateSell = this.$watch(
function() {
return this.item.sell
},
function(sellPrice) {
// unmount other watchers which can cause bounce effect
this.updateMargin()
// update margin
this.setMargin(sellPrice)
// re-add watchers
this.resetWatchers()
}
)
},
setSellPrice() {
let price = (100 / (100 - this.item.margin)) * this.item.net
this.item.sell = price.toFixed(2)
},
setMargin(sellPrice) {
let profit = (sellPrice - this.item.net)
let price = (100 * profit) / sellPrice
this.item.margin = price.toFixed(2)
}
}
})
new Vue({
el: '#vue',
data: {
prices: [
{
id: 1,
net: 5,
margin: 10,
sell: 5.56
},
{
id: 2,
net: 7,
margin: 10,
sell: 7.78
},
]
}
})
我相信我通过将观察程序安装在mounted()
调用方法来正确使用观察程序。并通过调用该方法重新初始化?
我真的希望你能帮忙。
下面是使用计算值的解决方案
每个参数(净值、保证金、卖出(都通过计算值进行抽象。getter 返回 this.item 值,资源库器首先更新 this.item 值,然后更新相关值。
这是一个与颜色选择器类似的问题,您可以在此处看到此问题的更复杂的版本 http://jsfiddle.net/Phunky/2enc99r1/
Vue.component('pricing', {
template: '#pricing-row',
props: ['item'],
computed: {
net:{
get () {
return Number(this.item.net)
},
set (net) {
this.item.net = Number(net)
this.setSellPrice()
}
},
margin:{
get () {
return this.item.margin
},
set (margin) {
this.item.margin = Number(margin)
this.setSellPrice()
}
},
sell:{
get () {
return this.item.sell
},
set (sell) {
this.item.sell = Number(sell)
this.setMargin()
}
}
},
methods: {
setSellPrice() {
let price = (100 / (100 - this.margin)) * this.net
this.item.sell = price.toFixed(2)
},
setMargin() {
let profit = (this.sell - this.net)
let price = (100 * profit) / this.sell
this.item.margin = Number(price.toFixed(2))
}
}
})
new Vue({
el: '#vue',
data: {
prices: [
{
id: 1,
net: 5,
margin: 10,
sell: 5.56
},
{
id: 2,
net: 7,
margin: 10,
sell: 7.78
},
]
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.5/vue.min.js"></script>
<script type="text/x-template" id="pricing-row">
<tr>
<td><input v-model="net" /></td>
<td><input v-model="margin" /></td>
<td><input v-model="sell" /></td>
</tr>
</script>
<div id="vue">
<table>
<tr>
<th>Net</th>
<th>Margin</th>
<th>Price</th>
</tr>
<tr is="pricing" v-for="(price, index) in prices" :item="price" :key="price.id"></tr>
</table>
</div>