原始系统中,只有采购量和消耗量,需要添加"余"列,并自动计算的余量
具体实现通过查询GPT获得:
提问:
使用antdesign vue的<a-table>组件做一个互动表,每行输入a和b两值,计算c=a+b,然后显示a、b、c
回答:
下面是使用 Ant Design Vue 的 <a-table>
组件创建一个互动表格,其中每行输入 a
和 b
的值,计算并显示 c = a + b
:
javascript
<template>
<a-table :dataSource="data" :columns="columns">
<template v-slot:title>Interactive Table</template>
<template v-slot:expanded-row="{ record }">
a: <a-input-number :value="record.a" @change="handleChange(record, 'a')" />
b: <a-input-number :value="record.b" @change="handleChange(record, 'b')" />
c: {{ record.c }}
</template>
</a-table>
</template>
<script>
export default {
data() {
return {
data: [
{ key: 1, a: 0, b: 0, c: 0 },
{ key: 2, a: 0, b: 0, c: 0 },
{ key: 3, a: 0, b: 0, c: 0 }
],
columns: [
{ title: 'Key', dataIndex: 'key' },
{ title: 'A', dataIndex: 'a' },
{ title: 'B', dataIndex: 'b' },
{ title: 'C', dataIndex: 'c' }
]
};
},
methods: {
handleChange(record, field) {
record[field] = parseFloat(record[field]);
record.c = record.a + record.b;
}
}
};
</script>
在上述示例中,我们使用了 <a-table>
组件来创建表格,并使用 :dataSource
和 :columns
属性将数据和列定义传递给表格组件。
在 <template v-slot:expanded-row>
中,我们定义了每行展开的内容。在展开的内容中,我们使用 <a-input-number>
组件来输入 a
和 b
的值。v-model
指令绑定了输入框的值到 record.a
和 record.b
,使其与数据源中对应的值保持同步。
通过 @change
事件监听输入框值的变化,调用 handleChange
方法更新数据源中的值,并计算 c
的值。最后,我们通过插值表达式 {``{ record.c }}
显示 c
的结果。
这样,每行输入 a
和 b
的值后,c
的值会自动计算并显示在表格中。、
提问:
限制<a-input-number>输入的数字保留小数点后两位
回答:
要限制 <a-input-number>
输入的数字保留小数点后两位,你可以使用 :precision
属性和 toFixed
方法。
下面是修改后的示例代码:
javascript
<template>
<a-table :dataSource="data" :columns="columns">
<template v-slot:title>Interactive Table</template>
<template v-slot:expanded-row="{ record }">
a: <a-input-number :value="record.a" @change="handleChange(record, 'a')" :precision="2" />
b: <a-input-number :value="record.b" @change="handleChange(record, 'b')" :precision="2" />
c: {{ record.c.toFixed(2) }}
</template>
</a-table>
</template>
<script>
export default {
data() {
return {
data: [
{ key: 1, a: 0, b: 0, c: 0 },
{ key: 2, a: 0, b: 0, c: 0 },
{ key: 3, a: 0, b: 0, c: 0 }
],
columns: [
{ title: 'Key', dataIndex: 'key' },
{ title: 'A', dataIndex: 'a' },
{ title: 'B', dataIndex: 'b' },
{ title: 'C', dataIndex: 'c' }
]
};
},
methods: {
handleChange(record, field) {
record[field] = parseFloat(record[field]);
record.c = record.a + record.b;
}
}
};
</script>
ps:
toFixed(2) 是js自带函数
成品代码:
javascript
<template>
<a-drawer
title="物品入库"
:maskClosable="false"
placement="right"
:closable="false"
:visible="show"
:width="1200"
@close="onClose"
style="height: calc(100% - 55px);overflow: auto;padding-bottom: 53px;"
>
<a-form :form="form" layout="horizontal">
<a-row :gutter="32">
<a-col :span="12">
<a-form-item label='保管人' v-bind="formItemLayout">
<a-input v-decorator="[
'custodian',
{ rules: [{ required: true, message: '请输入保管人!' }] }
]"/>
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label='入库人' v-bind="formItemLayout">
<a-input v-decorator="[
'putUser',
{ rules: [{ required: true, message: '请输入入库人!' }] }
]"/>
</a-form-item>
</a-col>
<a-col :span="24">
<a-form-item label='备注消息' v-bind="formItemLayout">
<a-textarea :rows="4" v-decorator="[
'content',
{ rules: [{ required: true, message: '请输入名称!' }] }
]"/>
</a-form-item>
</a-col>
<a-col :span="24">
<a-table :columns="columns" :data-source="dataList">
<template slot="nameShow" slot-scope="text, record">
<a-input v-model="record.name"></a-input>
</template>
<template slot="typeShow" slot-scope="text, record">
<a-input v-model="record.type"></a-input>
</template>
<template slot="typeIdShow" slot-scope="text, record">
<a-select v-model="record.typeId" style="width: 100%">
<a-select-option v-for="(item, index) in consumableType" :value="item.id" :key="index">{{ item.name }}</a-select-option>
</a-select>
</template>
<template slot="unitShow" slot-scope="text, record">
<a-input v-model="record.unit"></a-input>
</template>
<template slot="amountShow" slot-scope="text, record">
<a-input-number v-model="record.amount" :min="1" :step="1" :precision="2" @change="handleChange(record)"/>
</template>
<template slot="consumptionShow" slot-scope="text, record">
<a-input-number v-model="record.consumption" :min="0" :max="record.amount" :step="1" :precision="2" @change="handleChange(record)"/>
</template>
<template slot="priceShow" slot-scope="text, record">
<a-input-number v-model="record.price" :min="0"/>
</template>
</a-table>
<a-button @click="dataAdd" type="primary" ghost size="large" style="margin-top: 10px;width: 100%">
新增物品
</a-button>
</a-col>
</a-row>
</a-form>
<div class="drawer-bootom-button">
<a-popconfirm title="确定放弃编辑?" @confirm="onClose" okText="确定" cancelText="取消">
<a-button style="margin-right: .8rem">取消</a-button>
</a-popconfirm>
<a-button @click="handleSubmit" type="primary" :loading="loading">提交</a-button>
</div>
</a-drawer>
</template>
<script>
import {mapState} from 'vuex'
const formItemLayout = {
labelCol: { span: 24 },
wrapperCol: { span: 24 }
}
export default {
name: 'stockAdd',
props: {
stockAddVisiable: {
default: false
}
},
computed: {
...mapState({
currentUser: state => state.account.user
}),
show: {
get: function () {
return this.stockAddVisiable
},
set: function () {
}
},
columns () {
return [{
title: '序号',
dataIndex: 'key'
}, {
title: '物品名称',
dataIndex: 'name',
scopedSlots: {customRender: 'nameShow'}
}, {
title: '所属类型',
dataIndex: 'typeId',
width: 200,
scopedSlots: {customRender: 'typeIdShow'}
}, {
title: '型号',
dataIndex: 'type',
scopedSlots: {customRender: 'typeShow'}
}, {
title: '采购量',
dataIndex: 'amount',
scopedSlots: {customRender: 'amountShow'}
}, {
title: '消耗量',
dataIndex: 'consumption',
scopedSlots: {customRender: 'consumptionShow'}
}, {
title: '余',
dataIndex: 'balance'
}, {
title: '单位',
dataIndex: 'unit',
scopedSlots: {customRender: 'unitShow'}
}, {
title: '单价',
dataIndex: 'price',
scopedSlots: {customRender: 'priceShow'}
}]
}
},
mounted () {
this.getConsumableType()
},
data () {
return {
dataList: [],
formItemLayout,
form: this.$form.createForm(this),
loading: false,
consumableType: [],
keynumber: 1
}
},
methods: {
getConsumableType () {
this.$get('/cos/consumable-type/list').then((r) => {
this.consumableType = r.data.data
})
},
dataAdd () {
this.dataList.push({key: this.keynumber++, name: '', type: '', typeId: '', unit: '', amount: 0, consumption: 0, balance: 0, price: 0})
},
reset () {
this.loading = false
this.form.resetFields()
},
onClose () {
this.reset()
this.$emit('close')
},
handleChange (record) {
record.balance = (record.amount - record.consumption).toFixed(2)
},
handleSubmit () {
let price = 0
this.dataList.forEach(item => {
price += item.price * item.amount
})
this.form.validateFields((err, values) => {
values.price = price
values.goods = JSON.stringify(this.dataList)
if (!err) {
this.loading = true
this.$post('/cos/stock-info/put', {
...values
}).then((r) => {
this.reset()
this.$emit('success')
}).catch(() => {
this.loading = false
})
}
})
}
}
}
</script>
<style scoped>
</style>
开始我犯了两个错误:
①把@change="handleChange(record)"加到了<template slot="consumptionShow" slot-scope="text, record">上,应该加到<a-input-number>上才对。
②data-source数据项没有加如key列,编译报错。看了提示信息,感觉到不加key,程序无法将单行record对应到数组中的具体项,无法绑定数组中的数据。有了key才能绑定,这与vue标签的v-for属性
循环类似。