完整代码最下面会呈现给大家,这里主要将几个需要注意的点。
第一,结构的最上边是标题栏,但是由于标题栏默认时,当我们添加按钮时会超出界限,所以需要控制一下输入框的长度就没问题了。
.product-name-input {
width: 200px;
}
第二,树形结构的表格,需要特别注意行数据和列数据都需要唯一的key,如果没有指定唯一的key会出现一些稀奇古怪的错误。一些静态数据,想我的例子,手动赋值key,当我们时请求后台数据时,可以使用rowKey参数,record.id此处的id指你的数据dataSource中的id字段。
<a-table :columns="columns" :data-source="dataSource" bordered :customRow="showModal"
childrenColumnName="provicechildren" :rowKey="record => record.key" :pagination="dataParams">
</a-table>
第三,树形结构的表格,还需要注意的一个点就是我们后台传过来的数据,子数据可能并不是children,这个时候我们可以使用childrenColumnName参数指定我们的子数据。
const dataSource = ref([
{
key: 1,
name: 'John Brown sr.',
age: 60,
address: 'New York No. 1 Lake Park',
provicechildren: [ //默认时children
{
key: 11,
name: 'John Brown',
age: 42,
address: 'New York No. 2 Lake Park',
},
]
}
]);
第四,在树形表格结构中加上可编辑的单元格,从代码中我们就已经看出,在编辑和保存时,我们都需要key,所以key的存在和唯一性是非常重要的。并且我们可以根据每列的名称选择编辑哪列。
<template #bodyCell="{ column, text, record }">
<template v-if="column.dataIndex === 'age'">
<div class="editable-cell">
<div v-if="editableData[record.key]" class="editable-cell-input-wrapper">
<a-input v-model:value="editableData[record.key].age" @pressEnter="save(record.key)" />
<check-outlined class="editable-cell-icon-check" @click="save(record.key)" />
</div>
<div v-else class="editable-cell-text-wrapper">
{{ text || ' ' }}
<edit-outlined class="editable-cell-icon" @click="edit(record.key)" />
</div>
</div>
</template>
</template>
完整代码如下:
<template>
<a-page-header title="XXXXX">
<template #extra>
<a-input class="product-name-input" placeholder="请输入省份名称" v-model:value="searchText" />
<a-button @click="queryProvinceTree()">查询</a-button>
<a-button @click="reset()">重置</a-button>
</template>
</a-page-header>
<a-table :columns="columns" :data-source="dataSource" bordered :customRow="showModal"
childrenColumnName="provicechildren" :rowKey="record => record.key" :pagination="dataParams">
<template #bodyCell="{ column, text, record }">
<template v-if="column.dataIndex === 'age'">
<div class="editable-cell">
<div v-if="editableData[record.key]" class="editable-cell-input-wrapper">
<a-input v-model:value="editableData[record.key].age" @pressEnter="save(record.key)" />
<check-outlined class="editable-cell-icon-check" @click="save(record.key)" />
</div>
<div v-else class="editable-cell-text-wrapper">
{{ text || ' ' }}
<edit-outlined class="editable-cell-icon" @click="edit(record.key)" />
</div>
</div>
</template>
</template>
</a-table>
</template>
<script setup>
import { computed, defineComponent, reactive, ref } from 'vue';
import { CheckOutlined, EditOutlined } from '@ant-design/icons-vue';
import { cloneDeep } from 'lodash';
CheckOutlined
EditOutlined
const searchText = ref("");
const columns = [
{
title: 'Name',
dataIndex: 'name',
key: 'name',
},
{
title: 'Age',
dataIndex: 'age',
key: 'age',
width: '12%',
},
{
title: 'Address',
dataIndex: 'address',
width: '30%',
key: 'address',
},
];
const dataSource = ref([
{
key: 1,
name: 'John Brown sr.',
age: 60,
address: 'New York No. 1 Lake Park',
provicechildren: [
{
key: 11,
name: 'John Brown',
age: 42,
address: 'New York No. 2 Lake Park',
},
{
key: 12,
name: 'John Brown jr.',
age: 30,
address: 'New York No. 3 Lake Park',
provicechildren: [
{
key: 121,
name: 'Jimmy Brown',
age: 16,
address: 'New York No. 3 Lake Park',
},
],
},
{
key: 13,
name: 'Jim Green sr.',
age: 72,
address: 'London No. 1 Lake Park',
chilprovicechildrendren: [
{
key: 131,
name: 'Jim Green',
age: 42,
address: 'London No. 2 Lake Park',
provicechildren: [
{
key: 1311,
name: 'Jim Green jr.',
age: 25,
address: 'London No. 3 Lake Park',
},
{
key: 1312,
name: 'Jimmy Green sr.',
age: 18,
address: 'London No. 4 Lake Park',
},
],
},
],
},
],
},
{
key: 2,
name: 'Joe Black',
age: 32,
address: 'Sidney No. 1 Lake Park',
},
{
key: 3,
name: 'Joe Black',
age: 32,
address: 'Sidney No. 1 Lake Park',
},
{
key: 4,
name: 'Joe Black',
age: 32,
address: 'Sidney No. 1 Lake Park',
},
{
key: 5,
name: 'Joe Black',
age: 32,
address: 'Sidney No. 1 Lake Park',
},
{
key: 6,
name: 'Joe Black',
age: 32,
address: 'Sidney No. 1 Lake Park',
},
]);
const dataParams = reactive({
current: 1,
pageSize: 5,
})
//查询省份树--请求后台接口
const queryProvinceTree = () => {
console.log("查询省份树!");
}
//清空查询条件
const reset = () => {
searchText.value = "";
};
// 翻页事件--并且同时需要刷新列表
const tableChange = (option) => {
dataParams.current = option.current
}
const editableData = reactive({});
const edit = key => {
debugger
editableData[key] = cloneDeep(dataSource.value.filter(item => key === item.key)[0]);
console.log(key)
};
const save = key => {
Object.assign(dataSource.value.filter(item => key === item.key)[0], editableData[key]);
delete editableData[key];
};
</script>
<style scoped>
.product-name-input {
width: 200px;
}
.editable-cell-input-wrapper,
.editable-cell-text-wrapper {
padding-right: 24px;
}
.editable-cell-text-wrapper {
padding: 5px 24px 5px 5px;
}
.editable-cell-icon,
.editable-cell-icon-check {
position: absolute;
right: 0;
width: 20px;
cursor: pointer;
}
.editable-cell-icon {
margin-top: 4px;
margin-right: 10px;
}
.editable-cell-icon-check {
margin-top: 8px;
margin-right: 10px;
}
</style>