场景复现
子表单数据集formData
本人在进行表格子表单的数据进行监听时,通过一个数据的改变去实时响应改变其他数据,此时的数据会再次出发watch监听,而且在添加新的一行数据时也会触发,从而大大的影响性能,所以可以采取一下处理方式:
- 使用
watch
的deep
选项,避免深度监听对象的变化。 - 使用
throttle
或debounce
函数,限制函数的执行频率。 - 使用
computed
属性,将计算属性缓存起来,避免重复计算。
对于方式1,因为子表单的数据源是formData下的对象属性,必须采取深层监听,因此不采取
对于方式3,因为被该改变的值也是子表单数据源formData的一个对象属性,所以不采取
最终采取【节流】函数控制
添加【节流】函数前
/** 监听变化,计算总价 */
watch(
() => formData.value,
(val) => {
if (!val || val.length === 0) {
return;
}
// 循环处理
val.forEach((item) => {
// 税金=(施工费(不含税)+其他费(不含税)+辅材费(不含税))*结算税率(合同)+主材费(不含税)*他采主材费税率
item.tax=((item.constructionCostExcludeTax??0)+
(item.otherExcludeTax??0)+
(item.auxiliaryMaterialExcludeTax??0))*(item.incomeTax/100)??0+
(item.outsourcingMainMaterialsExcludeTax??0)*(item.incomeTax/100)??0;
// 计算成本小计(含税)
item.costIncludeTax = item.costExcludeTax + item.tax;
// 计算成本小计(不含税)
item.costExcludeTax =
item.constructionCostExcludeTax +
item.outsourcingMainMaterialsExcludeTax +
item.auxiliaryMaterialExcludeTax +
item.otherExcludeTax;
});
},
{ deep: true }
);
添加【节流】函数前
//节流函数
const throttle=(fn, time)=> {
let temp = false;
return function () {
if (temp) {
return;
} else {
temp = true; //节流阀设置为true
setTimeout(() => {
fn.apply(this, arguments);
temp = false;
}, time);
}
};
}
//表格数据逻辑计算函数
const chanTableItems=(val)=>{
val.forEach((item) => {
// 税金=(施工费(不含税)+其他费(不含税)+辅材费(不含税))*结算税率(合同)+主材费(不含税)*他采主材费税率
item.tax=((item.constructionCostExcludeTax??0)+
(item.otherExcludeTax??0)+
(item.auxiliaryMaterialExcludeTax??0))*(item.incomeTax/100)??0+
(item.outsourcingMainMaterialsExcludeTax??0)*(item.incomeTax/100)??0;
// 计算成本小计(含税)
item.costIncludeTax = item.costExcludeTax + item.tax;
// 计算成本小计(不含税)
item.costExcludeTax =
item.constructionCostExcludeTax +
item.outsourcingMainMaterialsExcludeTax +
item.auxiliaryMaterialExcludeTax +
item.otherExcludeTax;
}
//监听表格数据变化
watch(
() => formData.value,
(val) => {
if (!val || val.length === 0) {
return;
}
throttle(chanTableItems(val,500)
},
{ deep: true }
);