<template>
<div class="app-container">
<a-form class="table-page-search-wrapper" :model="query" ref="queryRef">
<a-row :gutter="10">
<a-col :span="6">
<a-form-item label="编码" name="code">
<a-input v-model:value="query.code" placeholder="编码" allowCLear />
</a-form-item>
</a-col>
<a-col :span="6">
<a-space>
<a-button type="primary" @click="handelSearch">查询</a-button>
<a-button @click="handelReset">重置</a-button>
</a-space>
</a-col>
</a-row>
</a-form>
<div style="margin: 10px 0">
<a-button @click="handleAdd" type="primary">新增</a-button>
</div>
<sv-table
:data="list"
v-loading="loading"
:height="500"
:span-method="spanMethod"
>
<sv-column
v-for="(item, index) in tableOptions.columns"
:key="index"
:title="item.title"
:field="item.field"
></sv-column>
</sv-table>
<s-pagination
v-show="total > 0"
:total="total"
v-model:current="pager.pageNum"
v-model:pageSize="pager.pageSize"
@change="getList"
/>
</div>
</template>
<script setup>
const query = ref({})
const total = ref(0)
const pager = ref({
pageNum: 1,
pageSize: 20
})
const list = ref([])
const loading = ref(false)
const addRef = ref()
const tableOptions = ref({})
function handelSearch() {
getList()
}
function initTable() {
const columns = [
{
title: 'id',
field: 'id'
},
{
title: '供应商',
field: 'supplierName'
},
{
title: '商品名称',
field: 'goodsName'
},
{
title: '商品code',
field: 'goodsCode'
},
{
title: '项目',
field: 'project'
},
{
title: '202401',
field: '202401'
},
{
title: '202402',
field: '202402'
},
{
title: '202403',
field: '202403'
}
]
const mergeField = ['id', 'supplierName', 'goodsName', 'goodsCode']
const mergeFieldIndex = mergeField.map((field) =>
columns.findIndex((item) => item.field === field)
)
tableOptions.value = {
columns,
mergeField,
mergeFieldIndex
}
}
function handelReset() {
query.value = {}
}
function handleDelete(id) {
console.log(id)
}
function handleAdd() {
addRef.value.open()
}
function handleEdit() {}
async function getList() {
loading.value = true
try {
const { data, total: totalNum } = await new Promise((resolve, reject) => {
resolve({
data: [
{
id: 1,
supplierName: '供应商1',
goodsName: '商品名称1',
goodsCode: '商品code',
projects: [
{
title: '成品库存',
data: {
202401: 10,
202402: 10,
202403: 10
}
},
{
title: '库存调整数量',
data: {
202401: 10,
202402: 10,
202403: 10
}
}
]
}
],
total: 10
})
})
list.value = handleData(data) // 处理数据
total.value = totalNum
} finally {
loading.value = false
}
}
function handleData(list) {
let result = []
for (let i = 0; i < list.length; i++) {
const projects = list[i].projects
for (let k = 0; k < projects.length; k++) {
const project = projects[k]
let item = {
...list[i],
project: project.title,
pid: list[i].id
}
Object.entries(project.data).forEach(([key, value]) => {
item[key] = value
})
result.push(item)
}
}
return result
}
const groupedData = computed(() => {
const map = new Map()
list.value.forEach((row) => {
const pid = row.pid
if (!map.has(pid)) {
map.set(pid, {
span: 1
})
} else {
map.get(pid).span++
}
})
return map
})
const spanMethod = ({ row, column, rowIndex, columnIndex }) => {
const fieldsIndex = tableOptions.value.mergeFieldIndex
if (fieldsIndex.includes(columnIndex)) {
const pid = row.pid
const group = groupedData.value.get(pid)
if (group) {
if (rowIndex === list.value.findIndex((r) => r.pid === pid)) {
return {
rowspan: group.span,
colspan: 1
}
} else {
return {
rowspan: 0,
colspan: 0
}
}
}
}
return {}
}
initTable() // 初始化table
</script>
<style scoped lang="scss"></style>
vue 3.2 + sv-table(二次封装vxe,使用将 sv 替换为 vxe 即可) 合并功能
于 2024-04-11 16:23:23 首次发布