我有一个带有表格行的组件,其中我有多个字段。通过 更新一个字段将使用基于保证金或卖出价格的值更新另一个字段。
但是当我正在观察所有领域时,我会得到一个弹跳效果。添加_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()
调用方法安装在观察者身上来正确使用观察者。通过回忆那种方法重新初始化?
我真的希望你能提供帮助。
答案 0 :(得分:0)
这是使用计算值的解决方案
每个参数(净值,保证金,卖出价)都是通过计算值抽象出来的。 getter返回this.item值,setter首先更新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>