Ant Design Vue 3 有多个可编辑单元格时如何select单单元格?
How to select single cell when there are multiple editable cells on Ant Design Vue 3?
现在我需要一些方法来制作我的 table editable 上的所有单元格。我知道我可以像 this example 那样做。但它每行只有一个单元格,我想知道如何使用自己的 v 模型为一行中的所有单元格实现这一点。我一直在寻找例子,但找不到任何例子。有谁知道我该怎么做?
我可以编辑所有这些,但是当我单击它时,它会打开所有单元格的编辑模式,而实际上我只想打开我单击的单元格。
这就是我的代码现在的样子:
<template>
<a-table bordered :data-source="dataSource" :columns="columns" :pagination="false">
<template #title>
<div class="formLayoutCrud">
<p>{{this.title}}</p>
<input-multiple-button :name="'buttonOptions'" :value="'percentage'" :options="this.buttonOptions"> </input-multiple-button>
</div>
</template>
<template v-for="col in this.editableCells" #[col]="{ text, record }" :key="col">
<div class="editable-cell">
<div v-if="editableData[record.key]" class="editable-cell-input-wrapper">
<a-input v-model:value="editableData[record.key][col]" @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, col)" />
</div>
</div>
</template>
</a-table>
</template>
<script>
import { reactive, ref } from 'vue';
import { CheckOutlined, EditOutlined } from '@ant-design/icons-vue';
import InputMultipleButton from '@/components/crudForm/InputMultipleButton.vue';
export default {
name: 'TableEditable',
props: {
title: String,
buttonOptions: Array,
editableCells: Array,
dataSrc: Array
},
components: {
CheckOutlined,
EditOutlined,
InputMultipleButton
},
setup() {
const columns = [
{
title: 'Mon',
dataIndex: 'monday',
slots: {
customRender: 'monday',
},
},
{
title: 'Tue',
dataIndex: 'tuesday',
slots: {
customRender: 'tuesday',
},
},
{
title: 'Wed',
dataIndex: 'wednesday',
slots: {
customRender: 'wednesday',
},
},
{
title: 'Thr',
dataIndex: 'thursday',
slots: {
customRender: 'thursday',
},
},
{
title: 'Fri',
dataIndex: 'friday',
slots: {
customRender: 'friday',
},
},
{
title: 'Sat',
dataIndex: 'saturday',
slots: {
customRender: 'saturday',
},
},
{
title: 'Sun',
dataIndex: 'sunday',
slots: {
customRender: 'sunday',
},
},
];
const dataSource = ref([
{
key: '0',
monday: '0',
tuesday: '0',
wednesday: '0',
thursday: '0',
friday: '0',
saturday: '0',
sunday: '0'
}
]);
const editableData = reactive({});
const edit = (key, teste) => {
console.log(teste)
editableData[key] = JSON.parse(JSON.stringify(dataSource.value.filter(item => key === item.key)[0]));
};
const save = key => {
console.log(key)
Object.assign(dataSource.value.filter(item => key === item.key)[0], editableData[key]);
delete editableData[key];
};
return {
columns,
dataSource,
editableData,
edit,
save
};
},
}
</script>
提前致谢!
TL;DR:
使用组合键,例如 editableData[row + '|' + column]
定位行和列进行编辑。
example(我假设您打算 link)有几个缺点。
如果您能原谅我的“迂腐”,我将首先解释该示例的作用。我在这里保留了重要的部分:
// in template: @click="edit(record.key)"
// in setup:
const editableData = reactive({});
function edit(key){
editableData[key] = JSON.parse(
JSON.stringify(dataSource.value.filter((item) => key === item.key)[0])
);
}
editableData
是一个反应对象,它将存储两个参数,键和整个对象的副本。例如,分配 editableData[2] = {...}
将允许 save
方法将第三项(键)替换为更改后的副本。一个问题是同一行中的所有字段都绑定在一起。因此,如果您编辑两个,但只保存一个,则它们都会更新。第二个问题是无法确定要编辑的对象中的哪个特定值。此外,如果底层数据通过其他路径可变,则依赖于整个对象的副本可能会导致一些问题。
有几种不同的方法可以解决这个问题,但我只分享我认为最简单的方法,即使用复合键。
您可以使用 editableData[rowKey + "|"+ colKey] = 12
而不是 editableData[key] = {a copy of row object}
(12 是用户点击编辑时的值示例)
看起来像这样:
模板:
<template
v-for="col in editableCells"
#[col]="{ column, text, record }"
:key="col"
>
<div class="editable-cell">
<div
v-if="editableData[record.key + '|' + column.key]"
class="editable-cell-input-wrapper"
>
<a-input
v-model:value="editableData[record.key + '|' + column.key]"
@pressEnter="save(record.key, column.key)"
/>
<check-outlined
class="editable-cell-icon-check"
@click="save(record.key, column.key)"
/>
</div>
<div v-else class="editable-cell-text-wrapper">
{{ text || ' ' }}
<edit-outlined
class="editable-cell-icon"
@click="edit(record.key, column.key)"
/>
</div>
</div>
</template>
脚本:
const edit = (row, column) => {
editableData[row + '|' + column] = dataSource.value.filter(
(item) => row === item.key
)[0][column];
};
const save = (row, column) => {
dataSource.value[row][column] = editableData[row + '|' + column];
delete editableData[row + '|' + column];
};
我使用竖线字符作为分隔符来连接两个字符串,您可以省略它并只使用 row + column
,它应该解析为一个字符串并且不会导致任何问题。如果您有可能出现冲突的键(例如两者都是索引),这可能会很方便
现在我需要一些方法来制作我的 table editable 上的所有单元格。我知道我可以像 this example 那样做。但它每行只有一个单元格,我想知道如何使用自己的 v 模型为一行中的所有单元格实现这一点。我一直在寻找例子,但找不到任何例子。有谁知道我该怎么做?
我可以编辑所有这些,但是当我单击它时,它会打开所有单元格的编辑模式,而实际上我只想打开我单击的单元格。
这就是我的代码现在的样子:
<template>
<a-table bordered :data-source="dataSource" :columns="columns" :pagination="false">
<template #title>
<div class="formLayoutCrud">
<p>{{this.title}}</p>
<input-multiple-button :name="'buttonOptions'" :value="'percentage'" :options="this.buttonOptions"> </input-multiple-button>
</div>
</template>
<template v-for="col in this.editableCells" #[col]="{ text, record }" :key="col">
<div class="editable-cell">
<div v-if="editableData[record.key]" class="editable-cell-input-wrapper">
<a-input v-model:value="editableData[record.key][col]" @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, col)" />
</div>
</div>
</template>
</a-table>
</template>
<script>
import { reactive, ref } from 'vue';
import { CheckOutlined, EditOutlined } from '@ant-design/icons-vue';
import InputMultipleButton from '@/components/crudForm/InputMultipleButton.vue';
export default {
name: 'TableEditable',
props: {
title: String,
buttonOptions: Array,
editableCells: Array,
dataSrc: Array
},
components: {
CheckOutlined,
EditOutlined,
InputMultipleButton
},
setup() {
const columns = [
{
title: 'Mon',
dataIndex: 'monday',
slots: {
customRender: 'monday',
},
},
{
title: 'Tue',
dataIndex: 'tuesday',
slots: {
customRender: 'tuesday',
},
},
{
title: 'Wed',
dataIndex: 'wednesday',
slots: {
customRender: 'wednesday',
},
},
{
title: 'Thr',
dataIndex: 'thursday',
slots: {
customRender: 'thursday',
},
},
{
title: 'Fri',
dataIndex: 'friday',
slots: {
customRender: 'friday',
},
},
{
title: 'Sat',
dataIndex: 'saturday',
slots: {
customRender: 'saturday',
},
},
{
title: 'Sun',
dataIndex: 'sunday',
slots: {
customRender: 'sunday',
},
},
];
const dataSource = ref([
{
key: '0',
monday: '0',
tuesday: '0',
wednesday: '0',
thursday: '0',
friday: '0',
saturday: '0',
sunday: '0'
}
]);
const editableData = reactive({});
const edit = (key, teste) => {
console.log(teste)
editableData[key] = JSON.parse(JSON.stringify(dataSource.value.filter(item => key === item.key)[0]));
};
const save = key => {
console.log(key)
Object.assign(dataSource.value.filter(item => key === item.key)[0], editableData[key]);
delete editableData[key];
};
return {
columns,
dataSource,
editableData,
edit,
save
};
},
}
</script>
提前致谢!
TL;DR:
使用组合键,例如 editableData[row + '|' + column]
定位行和列进行编辑。
example(我假设您打算 link)有几个缺点。
如果您能原谅我的“迂腐”,我将首先解释该示例的作用。我在这里保留了重要的部分:
// in template: @click="edit(record.key)"
// in setup:
const editableData = reactive({});
function edit(key){
editableData[key] = JSON.parse(
JSON.stringify(dataSource.value.filter((item) => key === item.key)[0])
);
}
editableData
是一个反应对象,它将存储两个参数,键和整个对象的副本。例如,分配 editableData[2] = {...}
将允许 save
方法将第三项(键)替换为更改后的副本。一个问题是同一行中的所有字段都绑定在一起。因此,如果您编辑两个,但只保存一个,则它们都会更新。第二个问题是无法确定要编辑的对象中的哪个特定值。此外,如果底层数据通过其他路径可变,则依赖于整个对象的副本可能会导致一些问题。
有几种不同的方法可以解决这个问题,但我只分享我认为最简单的方法,即使用复合键。
您可以使用 editableData[rowKey + "|"+ colKey] = 12
而不是 editableData[key] = {a copy of row object}
(12 是用户点击编辑时的值示例)
看起来像这样:
模板:
<template
v-for="col in editableCells"
#[col]="{ column, text, record }"
:key="col"
>
<div class="editable-cell">
<div
v-if="editableData[record.key + '|' + column.key]"
class="editable-cell-input-wrapper"
>
<a-input
v-model:value="editableData[record.key + '|' + column.key]"
@pressEnter="save(record.key, column.key)"
/>
<check-outlined
class="editable-cell-icon-check"
@click="save(record.key, column.key)"
/>
</div>
<div v-else class="editable-cell-text-wrapper">
{{ text || ' ' }}
<edit-outlined
class="editable-cell-icon"
@click="edit(record.key, column.key)"
/>
</div>
</div>
</template>
脚本:
const edit = (row, column) => {
editableData[row + '|' + column] = dataSource.value.filter(
(item) => row === item.key
)[0][column];
};
const save = (row, column) => {
dataSource.value[row][column] = editableData[row + '|' + column];
delete editableData[row + '|' + column];
};
我使用竖线字符作为分隔符来连接两个字符串,您可以省略它并只使用 row + column
,它应该解析为一个字符串并且不会导致任何问题。如果您有可能出现冲突的键(例如两者都是索引),这可能会很方便