VUE3使用elementplus实现数字的复杂运算(完善中)

一、官方推荐
在 Vue3 中处理嵌套数组或循环计算时,可通过以下方式优化复杂数字运算逻辑:
1. 利用计算属性(computed
)处理响应式数据
在<script setup>语法糖中,对于依赖响应式数据的计算,优先使用 computed
自动追踪依赖并缓存结果:
const numbers = ref([4, 15, 1, 8]);
const sum = computed(() => numbers.value.reduce((acc, num) => acc + num, 0));
支持多层嵌套数组的聚合计算:
const nestedNumbers = ref([[12, 4], [3, 6]]);
const complexResult = computed(() =>
nestedNumbers.value.flat().reduce((acc, num) => (acc * num) / 2, 1)
);
2. 通过 reduce
实现循环计算
对数组或嵌套结构进行累加、累乘等操作:
// 示例:计算 ((12+4)*3)/6
const steps = [12, 4, 3, 6];
const result = steps.reduce((acc, val, index) => {
if (index === 0) return val;
if (index === 1) return acc + val;
if (index === 2) return acc * val;
return acc / val;
}, 0);
3. 递归处理嵌套数组
使用递归函数遍历嵌套数组结构并执行计算:
function deepCalculate(arr: any[]): number {
return arr.reduce((acc, item) => {
if (Array.isArray(item)) {
return acc + deepCalculate(item);
}
return acc + Number(item);
}, 0);
}
// 使用示例
const nestedArray = [[4, [15, 1]], 8];
const total = deepCalculate(nestedArray); // 4+15+1+8=28
4. 使用工具库简化复杂运算
- 引入
lodash
或math.js
处理高阶数学逻辑:
import { chain } from 'lodash';
const result = chain([4, 15, 1, 8])
.sum()
.multiply(2)
.value(); // (4+15+1+8)*2=56
二、实际应用
1、简单数字的运算,两数加减乘除,使用原始JS方法写在公共TS文件中,使用时调用
/**加法*/
export const NumberAdd=(arg1:any, arg2:any)=> {
var r1, r2, m, n;
try {
r1 = arg1.toString().split(".")[1].length
} catch (e) {
r1 = 0
}
try {
r2 = arg2.toString().split(".")[1].length
} catch (e) {
r2 = 0
}
m = Math.pow(10, Math.max(r1, r2))
n = (r1 >= r2) ? r1 : r2;
return ((arg1 * m + arg2 * m) / m).toFixed(n);
}
/**减法*/
export const NumberSub=(arg1:any, arg2:any)=> {
var re1, re2, m, n;
try {
re1 = arg1.toString().split(".")[1].length;
} catch (e) {
re1 = 0;
}
try {
re2 = arg2.toString().split(".")[1].length;
} catch (e) {
re2 = 0;
}
m = Math.pow(10, Math.max(re1, re2));
n = (re1 >= re2) ? re1 : re2;
return ((arg1 * m - arg2 * m) / m).toFixed(n);
}
/**乘法*/
export const NumberMul=(arg1:any, arg2:any)=> {
var m = 0;
var s1 = arg1.toString();
var s2 = arg2.toString();
try {
m += s1.split(".")[1].length;
} catch (e) {}
try {
m += s2.split(".")[1].length;
} catch (e) {}
return Number(s1.replace(".", "")) * Number(s2.replace(".", "")) / Math.pow(10, m);
}
/**除法(除数,被除数,保留的小数点后的位数 )*/
export const NumberDiv=(arg1:any, arg2:any,digit:any)=> {
var t1=0,t2=0,r1,r2;
try{t1=arg1.toString().split(".")[1].length}catch(e){}
try{t2=arg2.toString().split(".")[1].length}catch(e){}
r1=Number(arg1.toString().replace(".",""))
r2=Number(arg2.toString().replace(".",""))
//获取小数点后的计算值
var result= ((r1/r2)*Math.pow(10,t2-t1)).toString()
var result2=result.split(".")[1];
var result3 = 0;
if(result2 != undefined)
{
result2 = result2.substring(0,digit>result2.length?result2.length:digit);
result3 = Number(result.split(".")[0]+"."+result2);
}
else
{
result3 = Number(result);
}
return result3;
}
//加法
let aaa = Number(NumberAdd(12,13));
若参与运算的是一些FORM表单中的字段,而FORM表单又没有使用接口定义它包含的字段名称及其类型,则可以使用该方法直接调用,不需要使用其他方法先定义数字number类型。因为没有定义表单内容时,每一步对表单中字段的运算操作都需要定义或使用Number进行转换,比较麻烦。
如果不想通过以上方式实现两数字的加减乘除,可以使用官方推荐的方法。
2、如果遇到复杂运算,可以使用官方推荐的newFunction,尽量不要使用eval函数,如下图为封装到TS文件中的简化版。
/**方便实现动态表达式计算 */
export const calculate = (expression: string) => {
try {
return new Function(`return ${expression}`)();
} catch {
return NaN;
}
};
let a = ((15*12*13*2)/8)-7;
const result = Number(calculate(a));
3、如果参加运算的参数已经定义了类型是number类型,则可以直接参与运算,但一定要确保全局定义了number类型,比如同时使用FORM表单定义实体类(字段类型+字段名称)+<el-input-number>控件控制字段一定是数字类型输入,否则可能会出现某一步变成字符串拼接的情况。
而且要注意表单中字段实现了响应式数据,因此页面某个地方对字段做出不合理的赋值,比如赋值了非数字,则直接运算会出错。
//举例:
const a = ref<number>(10);//当ref括号内一定是数字时,前面的<number>可省略
const b = ref<number>(20);//当ref括号内一定是数字时,前面的<number>可省略
let c = a+b;//结果也是number类型