mirror of
https://github.com/pure-admin/vue-pure-admin.git
synced 2025-06-06 00:18:51 +08:00
feat: pure-admin-table
添加单元格编辑表格的简易用法 (#992)
* feat: `pure-admin-table`添加单元格编辑表格的简易用法
This commit is contained in:
parent
dbfd014209
commit
e46d3e57fe
@ -128,8 +128,8 @@ menus:
|
|||||||
hsSensitive: 敏感词过滤
|
hsSensitive: 敏感词过滤
|
||||||
hsPinyin: 汉语拼音
|
hsPinyin: 汉语拼音
|
||||||
hsdanmaku: 弹幕
|
hsdanmaku: 弹幕
|
||||||
hsPureTableBase: 基础用法(23个示例)
|
hsPureTableBase: 基础用法
|
||||||
hsPureTableHigh: 高级用法(11个示例)
|
hsPureTableHigh: 高级用法
|
||||||
hsPureTableEdit: 可编辑用法
|
hsPureTableEdit: 可编辑用法
|
||||||
hsboard: 艺术画板
|
hsboard: 艺术画板
|
||||||
hsMenuoverflow: 目录超出显示 Tooltip 文字提示
|
hsMenuoverflow: 目录超出显示 Tooltip 文字提示
|
||||||
|
@ -1,23 +1,27 @@
|
|||||||
const tableData = [
|
const tableData = [
|
||||||
{
|
{
|
||||||
|
id: 1,
|
||||||
name: "Tom",
|
name: "Tom",
|
||||||
sex: 0, // 0代表男 1代表女
|
sex: 0, // 0代表男 1代表女
|
||||||
hobby: 2,
|
hobby: 2,
|
||||||
date: "2024-03-17"
|
date: "2024-03-17"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
id: 2,
|
||||||
name: "Jack",
|
name: "Jack",
|
||||||
sex: 0,
|
sex: 0,
|
||||||
hobby: 1,
|
hobby: 1,
|
||||||
date: "2024-03-18"
|
date: "2024-03-18"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
id: 3,
|
||||||
name: "Lily",
|
name: "Lily",
|
||||||
sex: 1,
|
sex: 1,
|
||||||
hobby: 1,
|
hobby: 1,
|
||||||
date: "2024-03-19"
|
date: "2024-03-19"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
id: 4,
|
||||||
name: "Mia",
|
name: "Mia",
|
||||||
sex: 1,
|
sex: 1,
|
||||||
hobby: 3,
|
hobby: 3,
|
||||||
@ -44,4 +48,27 @@ const options = [
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
export { tableData, options };
|
const tableDataEdit = [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
name: "Tom",
|
||||||
|
address: "home"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
name: "Jack",
|
||||||
|
address: "office"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
name: "Lily",
|
||||||
|
address: "library"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 4,
|
||||||
|
name: "Mia",
|
||||||
|
address: "playground"
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
export { tableData, tableDataEdit, options };
|
||||||
|
@ -10,9 +10,9 @@ const { columns, dataList, onAdd, onDel } = useColumns();
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
<el-scrollbar height="700px">
|
<el-scrollbar height="540px">
|
||||||
<code>
|
<code>
|
||||||
<pre class="w-[700px]"> {{ dataList }}</pre>
|
<pre class="w-[400px]"> {{ dataList }}</pre>
|
||||||
</code>
|
</code>
|
||||||
</el-scrollbar>
|
</el-scrollbar>
|
||||||
<pure-table
|
<pure-table
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { toRefs } from "vue";
|
|
||||||
import { useColumns } from "./columns";
|
import { useColumns } from "./columns";
|
||||||
|
|
||||||
const { editMap, columns, dataList, onEdit, onSave, onCancel } = useColumns();
|
const { editMap, columns, dataList, onEdit, onSave, onCancel } = useColumns();
|
||||||
@ -7,9 +6,9 @@ const { editMap, columns, dataList, onEdit, onSave, onCancel } = useColumns();
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
<el-scrollbar height="700px">
|
<el-scrollbar>
|
||||||
<code>
|
<code>
|
||||||
<pre class="w-[700px]"> {{ dataList }}</pre>
|
<pre class="w-[400px]"> {{ dataList }}</pre>
|
||||||
</code>
|
</code>
|
||||||
</el-scrollbar>
|
</el-scrollbar>
|
||||||
<pure-table
|
<pure-table
|
||||||
|
87
src/views/pure-table/edit/demo3/columns.tsx
Normal file
87
src/views/pure-table/edit/demo3/columns.tsx
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
import { ref, computed } from "vue";
|
||||||
|
import { tableDataEdit } from "../data";
|
||||||
|
|
||||||
|
import EditPen from "@iconify-icons/ep/edit-pen";
|
||||||
|
import Check from "@iconify-icons/ep/check";
|
||||||
|
|
||||||
|
export function useColumns() {
|
||||||
|
const editMap = ref({});
|
||||||
|
const activeIndex = ref(-1);
|
||||||
|
const dataList = ref(tableDataEdit);
|
||||||
|
|
||||||
|
const editing = computed(() => {
|
||||||
|
return index => {
|
||||||
|
return editMap.value[index]?.editing;
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
const iconClass = computed(() => {
|
||||||
|
return (index, other = false) => {
|
||||||
|
return [
|
||||||
|
"cursor-pointer",
|
||||||
|
"ml-2",
|
||||||
|
"transition",
|
||||||
|
"delay-100",
|
||||||
|
other
|
||||||
|
? ["hover:scale-110", "hover:text-red-500"]
|
||||||
|
: editing.value(index) && ["scale-150", "text-red-500"]
|
||||||
|
];
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
const columns: TableColumnList = [
|
||||||
|
{
|
||||||
|
label: "姓名(可修改)",
|
||||||
|
prop: "name",
|
||||||
|
cellRenderer: ({ row, index }) => (
|
||||||
|
<div
|
||||||
|
class="flex-bc w-full h-[32px]"
|
||||||
|
onMouseenter={() => (activeIndex.value = index)}
|
||||||
|
onMouseleave={() => onMouseleave(index)}
|
||||||
|
>
|
||||||
|
{!editing.value(index) ? (
|
||||||
|
<p>{row.name}</p>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<el-input v-model={row.name} />
|
||||||
|
<iconify-icon-offline
|
||||||
|
icon={Check}
|
||||||
|
class={iconClass.value(index)}
|
||||||
|
onClick={() => onSave(index)}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
<iconify-icon-offline
|
||||||
|
v-show={activeIndex.value === index && !editing.value(index)}
|
||||||
|
icon={EditPen}
|
||||||
|
class={iconClass.value(index, true)}
|
||||||
|
onClick={() => onEdit(row, index)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "地址",
|
||||||
|
prop: "address"
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
function onMouseleave(index) {
|
||||||
|
editing.value[index]
|
||||||
|
? (activeIndex.value = index)
|
||||||
|
: (activeIndex.value = -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
function onEdit(row, index) {
|
||||||
|
editMap.value[index] = Object.assign({ ...row, editing: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
function onSave(index) {
|
||||||
|
editMap.value[index].editing = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
columns,
|
||||||
|
dataList
|
||||||
|
};
|
||||||
|
}
|
22
src/views/pure-table/edit/demo3/index.vue
Normal file
22
src/views/pure-table/edit/demo3/index.vue
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { useColumns } from "./columns";
|
||||||
|
|
||||||
|
const { columns, dataList } = useColumns();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="flex">
|
||||||
|
<el-scrollbar>
|
||||||
|
<code>
|
||||||
|
<pre class="w-[400px]"> {{ dataList }}</pre>
|
||||||
|
</code>
|
||||||
|
</el-scrollbar>
|
||||||
|
<pure-table
|
||||||
|
class="!w-[30vw]"
|
||||||
|
row-key="id"
|
||||||
|
border
|
||||||
|
:data="dataList"
|
||||||
|
:columns="columns"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
@ -1,5 +1,6 @@
|
|||||||
import Demo1 from "./demo1/index.vue";
|
import Demo1 from "./demo1/index.vue";
|
||||||
import Demo2 from "./demo2/index.vue";
|
import Demo2 from "./demo2/index.vue";
|
||||||
|
import Demo3 from "./demo3/index.vue";
|
||||||
|
|
||||||
const rendContent = (val: string) =>
|
const rendContent = (val: string) =>
|
||||||
`代码位置:src/views/pure-table/edit/${val}/index.vue`;
|
`代码位置:src/views/pure-table/edit/${val}/index.vue`;
|
||||||
@ -16,5 +17,11 @@ export const list = [
|
|||||||
content: rendContent("demo2"),
|
content: rendContent("demo2"),
|
||||||
title: "单行编辑",
|
title: "单行编辑",
|
||||||
component: Demo2
|
component: Demo2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "demo3",
|
||||||
|
content: rendContent("demo3"),
|
||||||
|
title: "单元格编辑",
|
||||||
|
component: Demo3
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
@ -1,133 +0,0 @@
|
|||||||
import { tableDataEdit } from "../data";
|
|
||||||
import { message } from "@/utils/message";
|
|
||||||
import { ref, computed, Transition } from "vue";
|
|
||||||
import { clone, delay } from "@pureadmin/utils";
|
|
||||||
import EditPen from "@iconify-icons/ep/edit-pen";
|
|
||||||
import Check from "@iconify-icons/ep/check";
|
|
||||||
|
|
||||||
// 温馨提示:修改整行方法雷同,将cellRenderer后面渲染的组件抽出来做对应处理即可
|
|
||||||
export function useColumns() {
|
|
||||||
// 修改值(可多个)
|
|
||||||
const inputValMap = ref({});
|
|
||||||
// 是否正处于修改状态(可多个)
|
|
||||||
const editStatus = ref({});
|
|
||||||
// 当前激活的单元格(唯一)
|
|
||||||
const activeIndex = ref(-1);
|
|
||||||
const dataList = ref(clone(tableDataEdit, true));
|
|
||||||
|
|
||||||
const comVal = computed(() => {
|
|
||||||
return index => {
|
|
||||||
return inputValMap.value[index]?.value;
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
const editing = computed(() => {
|
|
||||||
return index => {
|
|
||||||
return editStatus.value[index]?.editing;
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
const iconClass = computed(() => {
|
|
||||||
return (index, other = false) => {
|
|
||||||
return [
|
|
||||||
"cursor-pointer",
|
|
||||||
"ml-2",
|
|
||||||
"transition",
|
|
||||||
"delay-100",
|
|
||||||
other
|
|
||||||
? ["hover:scale-110", "hover:text-red-500"]
|
|
||||||
: editing.value(index) && ["scale-150", "text-red-500"]
|
|
||||||
];
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
const columns: TableColumnList = [
|
|
||||||
{
|
|
||||||
label: "ID(可修改)",
|
|
||||||
prop: "id",
|
|
||||||
// class="flex-bc" flex-bc 代表 flex justify-between items-center 具体看 src/style/tailwind.css 文件
|
|
||||||
cellRenderer: ({ row, index }) => (
|
|
||||||
<div
|
|
||||||
class="flex-bc w-full h-[32px]"
|
|
||||||
onMouseenter={() => (activeIndex.value = index)}
|
|
||||||
onMouseleave={() => onMouseleave(index)}
|
|
||||||
>
|
|
||||||
<p v-show={!editing.value(index)}>{row.id}</p>
|
|
||||||
<Transition enter-active-class="animate__animated animate__fadeInUp animate__faster">
|
|
||||||
<el-input
|
|
||||||
v-show={editing.value(index)}
|
|
||||||
modelValue={comVal.value(index)}
|
|
||||||
onInput={value => onChange(value, index)}
|
|
||||||
/>
|
|
||||||
</Transition>
|
|
||||||
<iconify-icon-offline
|
|
||||||
v-show={editing.value(index)}
|
|
||||||
icon={Check}
|
|
||||||
class={iconClass.value(index)}
|
|
||||||
onClick={() => onSure(index)}
|
|
||||||
/>
|
|
||||||
<iconify-icon-offline
|
|
||||||
v-show={activeIndex.value === index && !editing.value(index)}
|
|
||||||
icon={EditPen}
|
|
||||||
class={iconClass.value(index, true)}
|
|
||||||
onClick={() => onEdit(row, index)}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "日期",
|
|
||||||
prop: "date"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "姓名",
|
|
||||||
prop: "name"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "地址",
|
|
||||||
prop: "address"
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
function onEdit({ id }, index) {
|
|
||||||
inputValMap.value[index] = Object.assign({}, inputValMap.value[index], {
|
|
||||||
value: id
|
|
||||||
});
|
|
||||||
// 处于修改状态
|
|
||||||
editStatus.value[index] = Object.assign({}, editStatus.value[index], {
|
|
||||||
editing: true
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function onMouseleave(index) {
|
|
||||||
inputValMap.value[index]?.value
|
|
||||||
? (activeIndex.value = index)
|
|
||||||
: (activeIndex.value = -1);
|
|
||||||
}
|
|
||||||
|
|
||||||
function onChange(value, index) {
|
|
||||||
inputValMap.value[index].value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
function onSure(index) {
|
|
||||||
dataList.value[index].id = inputValMap.value[index].value;
|
|
||||||
message(
|
|
||||||
`您修改了第 ${index + 1} 行,修改后数据为:${JSON.stringify(
|
|
||||||
dataList.value[index]
|
|
||||||
)}`,
|
|
||||||
{
|
|
||||||
type: "success"
|
|
||||||
}
|
|
||||||
);
|
|
||||||
// 修改状态关闭
|
|
||||||
editStatus.value[index] = Object.assign({}, editStatus.value[index], {
|
|
||||||
editing: false
|
|
||||||
});
|
|
||||||
delay().then(() => (inputValMap.value[index].value = null));
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
columns,
|
|
||||||
dataList
|
|
||||||
};
|
|
||||||
}
|
|
@ -1,9 +0,0 @@
|
|||||||
<script setup lang="ts">
|
|
||||||
import { useColumns } from "./columns";
|
|
||||||
|
|
||||||
const { columns, dataList } = useColumns();
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<pure-table row-key="id" border :data="dataList" :columns="columns" />
|
|
||||||
</template>
|
|
@ -4,7 +4,6 @@ import RowDrag from "./drag/row/index.vue";
|
|||||||
import ColumnDrag from "./drag/column/index.vue";
|
import ColumnDrag from "./drag/column/index.vue";
|
||||||
import Contextmenu from "./contextmenu/index.vue";
|
import Contextmenu from "./contextmenu/index.vue";
|
||||||
import Excel from "./excel/index.vue";
|
import Excel from "./excel/index.vue";
|
||||||
import Edit from "./edit/index.vue";
|
|
||||||
import Watermark from "./watermark/index.vue";
|
import Watermark from "./watermark/index.vue";
|
||||||
import Print from "./prints/index.vue";
|
import Print from "./prints/index.vue";
|
||||||
import Echarts from "./echarts/index.vue";
|
import Echarts from "./echarts/index.vue";
|
||||||
@ -50,12 +49,6 @@ export const list = [
|
|||||||
title: "右键菜单",
|
title: "右键菜单",
|
||||||
component: Contextmenu
|
component: Contextmenu
|
||||||
},
|
},
|
||||||
{
|
|
||||||
key: "edit",
|
|
||||||
content: rendContent("edit"),
|
|
||||||
title: "单元格修改",
|
|
||||||
component: Edit
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
key: "excel",
|
key: "excel",
|
||||||
content: rendContent("excel"),
|
content: rendContent("excel"),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user