前言
在arcodesign vue 中实现可编辑表格,当单元格被点击时,会切换到编辑模式,再次点击就会取消编辑模式,通过保存按钮把数据传到后端,进行保存。
提示:以下是本篇文章正文内容,下面案例可供参考
一、创建一个表格
创建一个包含表格数据的data属性,并在template中渲染表格组件,将data中的数据绑定到表格中。这里使用a-table组件创建的表格。下面部分代码为index.vue
<a-table
row-key="id"
:loading="loading"
:columns="(cloneColumns as TableColumnData[])"
:data="Data"
:bordered="{wrapper:true,cell:true}"
:size="size"
:default-expand-all-rows="true"
ref="artable"
>
</a-table>
数据在data.ts文件中
import { computed } from 'vue';
import type { TableColumnData } from '@arco-design/web-vue/es/table/interface';
export const columns = computed<TableColumnData[]>(() => [
{
title: 'ID',
dataIndex: 'SWUTID',
align:'center',
},
{
title: '名称',
dataIndex: 'NM',
align:'center',
},
{
title: '班级',
dataIndex: 'classnm',
align:'center',
slotName: 'classnm',
},
{
title: '学校',
dataIndex: 'school',
align:'center',
slotName: 'school',
},
]);
二、为表格添加点击功能
为每一行添加点击事件。当用户点击行时,进入编辑模式。再次点击时,取消编辑模式。你可以使用@row-click事件来实现这个功能。
<a-table
row-key="id"
:loading="loading"
:columns="(cloneColumns as TableColumnData[])"
:data="Data"
:bordered="{wrapper:true,cell:true}"
:size="size"
:default-expand-all-rows="true"
ref="artable"
@row-click="handleRowClick"
>
function handleRowClick(record: Record<string, any>): void {
if (isInEditMode(record)) {
toggleEditMode(record);
} else {
inEditMode.value = { [record.ID]: true };
}
}
其中isInEditMode(),toggleEditMode()为判断是否在编辑状态的函数。
三、为表格添加编辑功能
在处于编辑模式的单元格中,显示一个输入框,以便用户可以编辑内容。在a-table标签中,使用template来定义单元格的样式。单元格内容需要双向绑定,因此可以使用v-model来绑定数据。以下代码为index.vue文件中。代码如下(示例):
<a-table
row-key="id"
:loading="loading"
:columns="(cloneColumns as TableColumnData[])"
:data="Data"
:bordered="{wrapper:true,cell:true}"
:size="size"
:default-expand-all-rows="true"
ref="artable"
@row-click="handleRowClick"
>
<template #classnm="{ record, column }">
<td @click="toggleEditMode(record)" :class="isInEditMode(record)? 'in-edit-mode' : ''">
<div class="cell-content">
{{ record[column.dataIndex] }}
</div>
<input v-show="isInEditMode(record)" type="text" v-model="record[column.dataIndex]" />
</td>
</template>
<template #school="{ record, column }">
<td @click="toggleEditMode(record)" :class="isInEditMode(record)? 'in-edit-mode' : ''">
<div class="cell-content">
{{ record[column.dataIndex] }}
</div>
<input v-show="isInEditMode(record)" type="text" v-model="record[column.dataIndex]" />
</td>
</template>
</a-table>
const inEditMode = ref<Record<string, boolean>>({});
const editedRecordsToSave = ref([]);
//用于判断当前行是否处于编辑状态
function isInEditMode(record: Record<string, any>): boolean {
return !!inEditMode.value[record.ID];
}
//用于切换当前行的编辑状态
function toggleEditMode(record: Record<string, any>): void {
inEditMode.value[record.ID] =!inEditMode.value[record.ID];
}
注意
:如果使用下面代码一定要在data.ts文件中加入下面图片框起来部分,并且名字对应起来:
<template #school="{ record, column }">
<td @click="toggleEditMode(record)" :class="isInEditMode(record)? 'in-edit-mode' : ''">
<div class="cell-content">
{{ record[column.dataIndex] }}
</div>
<input v-show="isInEditMode(record)" type="text" v-model="record[column.dataIndex]" />
</td>
</template>
四、保存数据
添加保存按钮,save为调用的接口,代码如下(示例):
<a-button type="primary" @click="saveData">
<template #icon>
<icon-search />
</template>
保存
</a-button>
function saveData(): void {
collectEditedRecords();
if (editedRecordsToSave.value.length === 0) {
Message.error("没有处于编辑状态的行数据,不需要保存");
return;
}
else{
const editedRecords = editedRecordsToSave.value;
// 将代理对象转换为普通对象
const plainRecords = editedRecords.map(record => Object.assign({}, record));
// 现在 plainRecords是一个包含普通对象的数组
save(plainRecords[0]).then(()=>{
Message.success("保存成功");
fetchData();
inEditMode.value= {};
});
}
}
四、完整代码
<a-button type="primary" @click="saveData">
<template #icon>
<icon-search />
</template>
保存
</a-button>
<a-table
row-key="id"
:loading="loading"
:columns="(cloneColumns as TableColumnData[])"
:data="Data"
:bordered="{wrapper:true,cell:true}"
:size="size"
:default-expand-all-rows="true"
ref="artable"
@row-click="handleRowClick"
>
<template #classnm="{ record, column }">
<td @click="toggleEditMode(record)" :class="isInEditMode(record)? 'in-edit-mode' : ''">
<div class="cell-content">
{{ record[column.dataIndex] }}
</div>
<input v-show="isInEditMode(record)" type="text" v-model="record[column.dataIndex]" />
</td>
</template>
<template #school="{ record, column }">
<td @click="toggleEditMode(record)" :class="isInEditMode(record)? 'in-edit-mode' : ''">
<div class="cell-content">
{{ record[column.dataIndex] }}
</div>
<input v-show="isInEditMode(record)" type="text" v-model="record[column.dataIndex]" />
</td>
</template>
</a-table>
const inEditMode = ref<Record<string, boolean>>({});
const editedRecordsToSave = ref([]);
function isInEditMode(record: Record<string, any>): boolean {
return !!inEditMode.value[record.SWUTID];
}
function toggleEditMode(record: Record<string, any>): void {
inEditMode.value[record.SWUTID] =!inEditMode.value[record.SWUTID];
}
function handleRowClick(record: Record<string, any>): void {
if (isInEditMode(record)) {
toggleEditMode(record);
} else {
inEditMode.value = { [record.SWUTID]: true };
}
}
// 收集处于编辑状态的行数据
function collectEditedRecords(): void {
editedRecordsToSave.value = renderData.value.filter((record) => isInEditMode(record));
}
// 保存更改
function saveData(): void {
collectEditedRecords();
if (editedRecordsToSave.value.length === 0) {
Message.error("没有处于编辑状态的行数据,不需要保存");
return;
}
else{
const editedRecords = editedRecordsToSave.value;
// 将代理对象转换为普通对象
const plainRecords = editedRecords.map(record => Object.assign({}, record));
// 现在 plainRecords是一个包含普通对象的数组
save(plainRecords[0]).then(()=>{
Message.success("保存成功");
fetchData();
inEditMode.value= {};
});
}
}