如何让Vue组件像Excel一样支持动态公式,实现自定义列计算逻辑

实现方案
1. 新增Vuex通用总计Getter
首先在Vuex配置的getters中添加通用计算方法,支持根据传入的state名称、公式动态计算总计值:
// Vuex store 配置新增 getters: { // 原有其他getters保持不变 getCalcTotal: (state) => (stateName, formula, calcColumns) => { const targetArr = state[stateName] || [] return targetArr.reduce((total, row) => { const rowCalcVal = formula(row, calcColumns) return total + Number(rowCalcVal || 0) }, 0) } }
2. 组件新增参数支持动态配置
在现有组件props基础上新增两个参数,满足公式和计算列自定义需求:
// 组件script的props新增 props: { // 原有props:stateName、headers、title、rows保持不变 // 新增:指定参与计算的列对应header.value字段 calcColumns: { type: Array, default: () => [] }, // 新增:动态公式,入参为当前行数据、calcColumns数组,返回当前行计算结果 formula: { type: Function, default: (row, calcColumns) => { // 默认逻辑为所有指定列求和 return calcColumns.reduce((sum, key) => sum + Number(row[key] || 0), 0) } } },
3. 组件计算属性适配
新增总计值计算逻辑,对接Vuex getter:
computed: { ...mapState({ stateArr(state) { return state[this.stateName]; }, }), // 引入新增的getter ...mapGetters(['getCalcTotal']), // 动态计算总计 total() { return this.getCalcTotal(this.stateName, this.formula, this.calcColumns) } },
4. 模板渲染逻辑修改
添加计算列渲染、替换固定总计值:
<!-- 行内列渲染部分新增计算列判断 --> <v-col v-for="(header, j) in headers" :key="j"> <div v-if="header.type == 'number'" class="text-center"> {{ i + 1 }} </div> <div v-if="header.type == 'input'"> <v-text-field outlined dense hide-details="auto" :value="item[header.value]" @input="commit(i, header.value, $event)" > </v-text-field> </div> <!-- 新增计算列渲染 --> <div v-if="header.type == 'calc'" class="text-center"> {{ formula(item, calcColumns) }} </div> </v-col> <!-- 底部总计部分替换固定值 --> <v-col> <h2 class="text-center">{{ total }}</h2> </v-col>
调用示例
父组件使用时可灵活自定义计算规则:
<CalcTable title="商品利润表" state-name="goodsProfitData" :rows="5" :headers="[ { text: '序号', type: 'number' }, { text: '售价', type: 'input', value: 'salePrice' }, { text: '成本', type: 'input', value: 'cost' }, { text: '销量', type: 'input', value: 'saleCount' }, { text: '利润', type: 'calc' } ]" :calc-columns="['salePrice', 'cost', 'saleCount']" :formula="(row, cols) => { // 自定义公式:(售价-成本)*销量 return (Number(row[cols[0]]) - Number(row[cols[1]])) * Number(row[cols[2]] || 0) }" />
内容的提问来源于stack exchange,提问作者Ezekiel
相关产品推荐
相关产品推荐

