在Ant Design Vue(v1.7.8)a-table组件中实现余额自动计算
一、目标
在Ant Design Vue <a-table>表格中实现余额自动计算,公式为:剩余量 = 库存量 - 消耗量
二、二次开发基础
现有一个使用Ant Design Vue <a-table>表格的开源项目,原始表格有“消耗量”列,且带输入框,数据双向绑定
三、项目结构
stock\Stock.vue ———— 父组件 内容是库存清单
stock\StockAdd.vue ———— 已开发的入库物品列表 可以参考
stock\StockOut.vue ———— 需要二次开发的组件 内容是出库物品列表
四、功能描述
原始功能:在父组件中选择要出库的物品,点击出库,弹出出库物品列表,填写消耗量并提交,然后回到库存清单,库存量变为原库存量减去消耗量后的剩余量
?修改后功能:在弹出的物品列表中添加库存量、剩余量两列只读数据,填写消耗量时,剩余量会随之变化,满足剩余量 = 库存量 - 消耗量。
?五、遇到的问题
出库物品列表StockOut.vue中<a-table>表格的出库数据,来自传入参数,是从父组件库存清单表中提取的。因为库存清单表中没有消耗量和剩余量数据列,传递过来的对象数组中不含这两个数据项。需要通过map函数遍历数据数组,为每个对象添加 key、consumption、balance 属性,否则剩余量不能一直跟随消耗量变化(只能变化一次)。
this.dataList = this.stockoutData.map(item => {
return {
...item,
key: item.id, // 加入父组件库存列表中不存在的key属性,使用 ID 值作为 key
consumption: 0, // 加入父组件库存列表中不存在的“消耗量”列
balance: item.amount // 加入父组件库存列表中不存在的“剩余量”列
}
})
其中,dataList是StockOut.vue本地数组,stockoutData是StockOut.vue组件参数,值由父组件传入。
以下是StockOut.vue的参数定义:
props: {
stockoutVisiable: {
default: false
},
stockoutData: {
type: Array
}
},
以下是Stock.vue中参数传递的代码:
<stock-out
@close="handleStockoutClose"
@success="handleStockoutSuccess"
:stockoutData="stockout.data"
:stockoutVisiable="stockout.visiable">
</stock-out>
入参stockoutData被赋值为stockout.data,而stockout.data来自所选的行数据this.selectedRows:
// “出库”按键的响应方法
outOfWarehouse () {
if (!this.selectedRowKeys.length) {
this.$message.warning('请选择需要出库的物品')
return
}
let goods = this.selectedRows
let amt = false
let warningwords = '某个物品'
goods.forEach(item => {
item.max = item.amount
if (item.amount === 0) {
amt = true
warningwords = item.name
}
})
if (amt) {
this.$message.warning(`${warningwords}没有库存!`)
return
}
this.stockout.data = JSON.parse(JSON.stringify(goods))
this.stockout.visiable = true
},
this.selectedRows的赋值在onSelectChange()函数中进行,onSelectChange()被设为<a-table>组件的响应函数。当选中每行前面的复选框时,this.selectedRows就会同步赋值为所选的行的数据。
<a-table ref="TableInfo"
:columns="columns"
:rowKey="record => record.id"
:dataSource="dataSource"
:pagination="pagination"
:loading="loading"
:rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}"
:scroll="{ x: 900 }"
@change="handleTableChange">
......
onSelectChange (selectedRowKeys, selectedRows) {
selectedRows.forEach(item => {
if (item.amount === 0) {
this.$message.warning(`${item.name}没有库存!`)
return false
}
})
this.selectedRowKeys = selectedRowKeys
this.selectedRows = selectedRows
},
由于<a-table>组件是封装好的,想通过老办法console.log()看<a-table>内部的变量值得改源码,读懂源码的难度很高,而通过vue的谷歌浏览器插件Vue.js devtools查看<a-table>内部的变量值就非常简单了。
?六、源码
stock\Stock.vue ———— 父组件 内容是库存清单
<template>
<a-card :bordered="false" class="card-area">
<div :class="advanced ? 'search' : null">
<!-- 搜索区域 -->
<a-form layout="horizontal">
<a-row :gutter="15">
<div :class="advanced ? null: 'fold'">
<a-col :md="6" :sm="24">
<a-form-item
label="物品名称"
:labelCol="{span: 4}"
:wrapperCol="{span: 18, offset: 2}">
<a-input v-model="queryParams.name"/>
</a-form-item>
</a-col>
<a-col :md="6" :sm="24">
<a-form-item
label="物品型号"
:labelCol="{span: 4}"
:wrapperCol="{span: 18, offset: 2}">
<a-input v-model="queryParams.type"/>
</a-form-item>
</a-col>
<a-col :md="6" :sm="24">
<a-form-item
label="物品类型"
:labelCol="{span: 4}"
:wrapperCol="{span: 18, offset: 2}">
<a-select v-model="queryParams.typeId" style="width: 100%" allowClear>
<a-select-option v-for="(item, index) in consumableType" :value="item.id" :key="index">{{ item.name }}</a-select-option>
</a-select>
</a-form-item>
</a-col>
</div>
<span style="float: right; margin-top: 3px;">
<a-button type="primary" @click="search">查询</a-button>
<a-button style="margin-left: 8px" @click="reset">重置</a-button>
</span>
</a-row>
</a-form>
</div>
<div>
<div class="operator">
<a-button type="primary" ghost @click="warehouse">入库</a-button>
<a-button type="primary" ghost @click="outOfWarehouse">出库</a-button>
<!--<a-button @click="batchDelete">删除</a-button>-->
</div>
<!-- 表格区域 -->
<a-table ref="TableInfo"
:columns="columns"
:rowKey="record => record.id"
:dataSource="dataSource"
:pagination="pagination"
:loading="loading"
:rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}"
:scroll="{ x: 900 }"
@change="handleTableChange">
<template slot="titleShow" slot-scope="text, record">
<template>
<a-badge status="processing"/>
<a-tooltip>
<template slot="title">
{{ record.title }}
</template>
{{ record.title.slice(0, 8) }} ...
</a-tooltip>
</template>
</template>
<template slot="contentShow" slot-scope="text, record">
<template>
<a-tooltip>
<template slot="title">
{{ record.content }}
</template>
{{ record.content.slice(0, 30) }} ...
</a-tooltip>
</template>
</template>
<template slot="operation" slot-scope="text, record">
<a-icon type="setting" theme="twoTone" twoToneColor="#4a9ff5" @click="edit(record)" title="修 改"></a-icon>
</template>
</a-table>
</div>
<!-- v-if="stockadd.visiable" StockAdd.vue中的a-drawer 有显示属性:visible="show" 不需要再使用v-if控制其是否显示 -->
<stock-add
@close="handleStockAddClose"
@success="handleStockAddSuccess"
:stockAddVisiable="stockadd.visiable">
</stock-add>
<stock-out
@close="handleStockoutClose"
@success="handleStockoutSuccess"
:stockoutData="stockout.data"
:stockoutVisiable="stockout.visiable">
</stock-out>
</a-card>
</template>
<script>
import RangeDate from '@/components/datetime/RangeDate'
import {mapState} from 'vuex'
import StockOut from './StockOut'
import StockAdd from './StockAdd'
import moment from 'moment'
moment.locale('zh-cn')
export default {
name: 'Stock',
components: {StockOut, StockAdd, RangeDate},
data () {
return {
advanced: false,
stockadd: {
visiable: false
},
stockout: {
visiable: false,
data: null
},
requestEdit: {
visiable: false
},
queryParams: {},
filteredInfo: null,
sortedInfo: null,
paginationInfo: null,
dataSource: [],
selectedRowKeys: [],
selectedRows: [],
loading: false,
pagination: {
pageSizeOptions: ['10', '20', '30', '40', '100'],
defaultCurrent: 1,
defaultPageSize: 10,
showQuickJumper: true,
showSizeChanger: true,
showTotal: (total, range) => `显示 ${range[0]} ~ ${range[1]} 条记录,共 ${total} 条记录`
},
consumableType: []
}
},
computed: {
...mapState({
currentUser: state => state.account.user
}),
columns () {
return [{
title: 'ID',
dataIndex: 'id'
}, {
title: '物品名称',
dataIndex: 'name'
}, {
title: '型号',
dataIndex: 'type',
customRender: (text, row, index) => {
if (text !== null) {
return text
} else {
return '- -'
}
}
}, {
title: '物品数量',
dataIndex: 'amount',
customRender: (text, row, index) => {
if (text !== null) {
return text
} else {
return '- -'
}
}
}, {
title: '单位',
dataIndex: 'unit',
customRender: (text, row, index) => {
if (text !== null) {
return text
} else {
return '- -'
}
}
}, {
title: '单价',
dataIndex: 'price',
customRender: (text, row, index) => {
if (text !== null) {
return '¥' + text.toFixed(2)
} else {
return '- -'
}
}
}, {
title: '总价',
dataIndex: 'allPrice',
customRender: (text, row, index) => {
return '¥' + (row.price * row.amount).toFixed(2)
}
}, {
title: '物品类型',
dataIndex: 'consumableType',
customRender: (text, row, index) => {
if (text !== null) {
return <a-tag>{text}</a-tag>
} else {
return '- -'
}
}
}, {
title: '备注',
dataIndex: 'content',
customRender: (text, row, index) => {
if (text !== null) {
return text
} else {
return '- -'
}
}
}, {
title: '入库时间',
dataIndex: 'createDate',
customRender: (text, row, index) => {
if (text !== null) {
return text
} else {
return '- -'
}
}
}]
}
},
mounted () {
this.fetch()
this.getConsumableType()
},
methods: {
getConsumableType () {
this.$get('/cos/consumable-type/list').then((r) => {
this.consumableType = r.data.data
})
},
onSelectChange (selectedRowKeys, selectedRows) {
selectedRows.forEach(item => {
if (item.amount === 0) {
this.$message.warning(`${item.name}没有库存!`)
return false
}
})
this.selectedRowKeys = selectedRowKeys
this.selectedRows = selectedRows
},
toggleAdvanced () {
this.advanced = !this.advanced
},
// “入库”按键响应
warehouse () {
this.stockadd.visiable = true
},
// “出库”按键的响应方法
outOfWarehouse () {
if (!this.selectedRowKeys.length) {
this.$message.warning('请选择需要出库的物品')
return
}
let goods = this.selectedRows
let amt = false
let warningwords = '某个物品'
goods.forEach(item => {
item.max = item.amount
if (item.amount === 0) {
amt = true
warningwords = item.name
}
})
if (amt) {
this.$message.warning(`${warningwords}没有库存!`)
return
}
this.stockout.data = JSON.parse(JSON.stringify(goods))
this.stockout.visiable = true
},
handleStockAddClose () {
this.stockadd.visiable = false
},
handleStockAddSuccess () {
this.stockadd.visiable = false
this.$message.success('入库成功')
this.search()
},
handleStockoutClose () {
this.stockout.visiable = false
},
handleStockoutSuccess () {
this.stockout.visiable = false
this.selectedRows = []
this.selectedRowKeys = []
this.$message.success('出库成功')
this.search()
},
handleDeptChange (value) {
this.queryParams.deptId = value || ''
},
batchDelete () {
if (!this.selectedRowKeys.length) {
this.$message.warning('请选择需要删除的记录')
return
}
let that = this
this.$confirm({
title: '确定删除所选中的记录?',
content: '当您点击确定按钮后,这些记录将会被彻底删除',
centered: true,
onOk () {
let ids = that.selectedRowKeys.join(',')
that.$delete('/cos/request-type/' + ids).then(() => {
that.$message.success('删除成功')
that.selectedRowKeys = []
that.selectedRows = []
that.search()
})
},
onCancel () {
that.selectedRowKeys = []
that.selectedRows = []
}
})
},
search () {
let {sortedInfo, filteredInfo} = this
let sortField, sortOrder
// 获取当前列的排序和列的过滤规则
if (sortedInfo) {
sortField = sortedInfo.field
sortOrder = sortedInfo.order
}
this.fetch({
sortField: sortField,
sortOrder: sortOrder,
...this.queryParams,
...filteredInfo
})
},
reset () {
// 取消选中
this.selectedRowKeys = []
// 重置分页
this.$refs.TableInfo.pagination.current = this.pagination.defaultCurrent
if (this.paginationInfo) {
this.paginationInfo.current = this.pagination.defaultCurrent
this.paginationInfo.pageSize = this.pagination.defaultPageSize
}
// 重置列过滤器规则
this.filteredInfo = null
// 重置列排序规则
this.sortedInfo = null
// 重置查询参数
this.queryParams = {}
this.fetch()
},
handleTableChange (pagination, filters, sorter) {
// 将这三个参数赋值给Vue data,用于后续使用
this.paginationInfo = pagination
this.filteredInfo = filters
this.sortedInfo = sorter
this.fetch({
sortField: sorter.field,
sortOrder: sorter.order,
...this.queryParams,
...filters
})
},
fetch (params = {}) {
// 显示loading
this.loading = true
if (this.paginationInfo) {
// 如果分页信息不为空,则设置表格当前第几页,每页条数,并设置查询分页参数
this.$refs.TableInfo.pagination.current = this.paginationInfo.current
this.$refs.TableInfo.pagination.pageSize = this.paginationInfo.pageSize
params.size = this.paginationInfo.pageSize
params.current = this.paginationInfo.current
} else {
// 如果分页信息为空,则设置为默认值
params.size = this.pagination.defaultPageSize
params.current = this.pagination.defaultCurrent
}
if (params.typeId === undefined) {
delete params.typeId
}
this.$get('/cos/stock-info/page', {
...params
}).then((r) => {
let data = r.data.data
const pagination = {...this.pagination}
pagination.total = data.total
this.dataSource = data.records
this.pagination = pagination
// 数据加载完毕,关闭loading
this.loading = false
})
}
},
watch: {}
}
</script>
<style lang="less" scoped>
@import "../../../../static/less/Common";
</style>
stock\StockAdd.vue ———— 已开发的入库物品列表 可以参考
<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>
stock\StockOut.vue ———— 需要二次开发的组件 内容是出库物品列表
<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="vertical">
<a-row :gutter="20">
<a-col :span="12">
<a-form-item label='出库对象' v-bind="formItemLayout">
<a-select v-decorator="[
'userId',
{ rules: [{ required: true, message: '请输入出库对象!' }] }
]" style="width: 100%">
<a-select-option v-for="(item, index) in studentList" :value="item.id" :key="index">{{ item.name
}}</a-select-option>
</a-select>
</a-form-item>
</a-col>
<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="[
'handler',
{ 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="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="1" />
</template>
</a-table>
</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: 'StockOut',
props: {
stockoutVisiable: {
default: false
},
stockoutData: {
type: Array
}
},
computed: {
...mapState({
currentUser: state => state.account.user
}),
show: {
get: function () {
return this.stockoutVisiable
},
set: function () {
}
},
columns () {
return [{
title: '序号',
dataIndex: 'key'
}, {
title: '物品名称',
dataIndex: 'name',
scopedSlots: { customRender: 'nameShow' }
}, {
title: '型号',
dataIndex: 'type',
scopedSlots: { customRender: 'typeShow' }
}, {
title: '库存量',
dataIndex: 'amount'
}, {
title: '消耗量',
dataIndex: 'consumption',
scopedSlots: { customRender: 'consumptionShow' }
}, {
title: '剩余量',
dataIndex: 'balance'
}, {
title: '所属类型',
dataIndex: 'typeId',
width: 200,
scopedSlots: { customRender: 'typeIdShow' }
}, {
title: '单位',
dataIndex: 'unit',
scopedSlots: { customRender: 'unitShow' }
}, {
title: '单价',
dataIndex: 'price',
scopedSlots: { customRender: 'priceShow' }
}]
}
},
data () {
return {
formItemLayout,
form: this.$form.createForm(this),
loading: false,
dataList: [],
consumableType: [],
studentList: []
}
},
watch: {
stockoutVisiable: function (value) {
if (value) {
this.dataList = this.stockoutData.map(item => {
return {
...item,
key: item.id, // 加入父组件库存列表中不存在的key属性,使用 ID 值作为 key
consumption: 0, // 加入父组件库存列表中不存在的“消耗量”列
balance: item.amount // 加入父组件库存列表中不存在的“剩余量”列
}
})
}
}
},
mounted () {
this.getConsumableType()
this.getStudentList()
},
methods: {
getStudentList () {
this.$get('/cos/student-info/list').then((r) => {
this.studentList = r.data.data
})
},
getConsumableType () {
this.$get('/cos/consumable-type/list').then((r) => {
this.consumableType = r.data.data
})
},
reset () {
this.loading = false
this.dataList = []
this.form.resetFields()
},
onClose () {
this.reset()
this.$emit('close')
},
handleChange (record) {
record.balance = (record.amount - record.consumption).toFixed(2)
},
handleSubmit () {
if (this.dataList.length !== 0) {
let price = 0
this.dataList.forEach(item => {
price += item.price * item.amount
})
this.form.validateFields((err, values) => {
if (!err) {
values.price = price
values.goods = JSON.stringify(this.dataList)
this.loading = true
this.$post('/cos/stock-out/stockOut', {
...values
}).then((r) => {
this.reset()
this.$emit('success')
}).catch(() => {
this.loading = false
})
}
})
} else {
this.$message.warning('添加出库记录')
}
}
}
}
</script>
<style scoped></style>
七、新的疑问
?columns必须是计算属性吗
computed: {
...mapState({
currentUser: state => state.account.user
}),
show: {
get: function () {
return this.stockoutVisiable
},
set: function () {
}
},
columns () {
return [{
title: '序号',
dataIndex: 'key'
}, {
title: '物品名称',
dataIndex: 'name',
scopedSlots: { customRender: 'nameShow' }
}, {
title: '型号',
dataIndex: 'type',
scopedSlots: { customRender: 'typeShow' }
}, {
title: '库存量',
dataIndex: 'amount'
}, {
title: '消耗量',
dataIndex: 'consumption',
scopedSlots: { customRender: 'consumptionShow' }
}, {
title: '剩余量',
dataIndex: 'balance'
}, {
title: '所属类型',
dataIndex: 'typeId',
width: 200,
scopedSlots: { customRender: 'typeIdShow' }
}, {
title: '单位',
dataIndex: 'unit',
scopedSlots: { customRender: 'unitShow' }
}, {
title: '单价',
dataIndex: 'price',
scopedSlots: { customRender: 'priceShow' }
}]
}
},
如何将后台api数据中的id列转为antdesignvue中的key?
AI参考答案:
要将后台 API 数据中的 ID 列转换为 Ant Design Vue 中的 key,你可以按照以下步骤进行操作:
首先,确保你已经使用 Ant Design Vue 创建了表格或其他组件,需要将数据作为数据源进行渲染。
在获取到后台 API 数据后,遍历数据数组中的每个对象。
对于每个对象,将其 ID 值提取出来,并将其赋值给一个名为 "key" 的属性。
最后,将更新后的数据数组作为数据源传递给 Ant Design Vue 的组件进行渲染。
以下是一段示例代码,展示了如何将后台 API 数据中的 ID 列转换为 Ant Design Vue 中的 key:
// 假设你已经从后台 API 获取到了数据数组 const apiData = [ { id: 1, name: 'John', age: 25 }, { id: 2, name: 'Jane', age: 30 }, // ... ]; // 遍历数据数组,为每个对象添加 key 属性 const transformedData = apiData.map(item => { return { ...item, key: item.id, // 使用 ID 值作为 key }; }); // 将更新后的数据传递给 Ant Design Vue 的组件进行渲染 <Table :dataSource="transformedData"> <!-- 表格列配置 --> <a-table-column title="ID" dataIndex="id" key="id" /> <a-table-column title="Name" dataIndex="name" key="name" /> <a-table-column title="Age" dataIndex="age" key="age" /> <!-- 更多列... --> </Table>
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!