mirror of
https://github.com/pure-admin/vue-pure-admin.git
synced 2025-06-04 07:27:41 +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: 敏感词过滤
|
||||
hsPinyin: 汉语拼音
|
||||
hsdanmaku: 弹幕
|
||||
hsPureTableBase: 基础用法(23个示例)
|
||||
hsPureTableHigh: 高级用法(11个示例)
|
||||
hsPureTableBase: 基础用法
|
||||
hsPureTableHigh: 高级用法
|
||||
hsPureTableEdit: 可编辑用法
|
||||
hsboard: 艺术画板
|
||||
hsMenuoverflow: 目录超出显示 Tooltip 文字提示
|
||||
|
@ -1,23 +1,27 @@
|
||||
const tableData = [
|
||||
{
|
||||
id: 1,
|
||||
name: "Tom",
|
||||
sex: 0, // 0代表男 1代表女
|
||||
hobby: 2,
|
||||
date: "2024-03-17"
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: "Jack",
|
||||
sex: 0,
|
||||
hobby: 1,
|
||||
date: "2024-03-18"
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: "Lily",
|
||||
sex: 1,
|
||||
hobby: 1,
|
||||
date: "2024-03-19"
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
name: "Mia",
|
||||
sex: 1,
|
||||
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>
|
||||
<div class="flex">
|
||||
<el-scrollbar height="700px">
|
||||
<el-scrollbar height="540px">
|
||||
<code>
|
||||
<pre class="w-[700px]"> {{ dataList }}</pre>
|
||||
<pre class="w-[400px]"> {{ dataList }}</pre>
|
||||
</code>
|
||||
</el-scrollbar>
|
||||
<pure-table
|
||||
|
@ -1,5 +1,4 @@
|
||||
<script setup lang="ts">
|
||||
import { toRefs } from "vue";
|
||||
import { useColumns } from "./columns";
|
||||
|
||||
const { editMap, columns, dataList, onEdit, onSave, onCancel } = useColumns();
|
||||
@ -7,9 +6,9 @@ const { editMap, columns, dataList, onEdit, onSave, onCancel } = useColumns();
|
||||
|
||||
<template>
|
||||
<div class="flex">
|
||||
<el-scrollbar height="700px">
|
||||
<el-scrollbar>
|
||||
<code>
|
||||
<pre class="w-[700px]"> {{ dataList }}</pre>
|
||||
<pre class="w-[400px]"> {{ dataList }}</pre>
|
||||
</code>
|
||||
</el-scrollbar>
|
||||
<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 Demo2 from "./demo2/index.vue";
|
||||
import Demo3 from "./demo3/index.vue";
|
||||
|
||||
const rendContent = (val: string) =>
|
||||
`代码位置:src/views/pure-table/edit/${val}/index.vue`;
|
||||
@ -16,5 +17,11 @@ export const list = [
|
||||
content: rendContent("demo2"),
|
||||
title: "单行编辑",
|
||||
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 Contextmenu from "./contextmenu/index.vue";
|
||||
import Excel from "./excel/index.vue";
|
||||
import Edit from "./edit/index.vue";
|
||||
import Watermark from "./watermark/index.vue";
|
||||
import Print from "./prints/index.vue";
|
||||
import Echarts from "./echarts/index.vue";
|
||||
@ -50,12 +49,6 @@ export const list = [
|
||||
title: "右键菜单",
|
||||
component: Contextmenu
|
||||
},
|
||||
{
|
||||
key: "edit",
|
||||
content: rendContent("edit"),
|
||||
title: "单元格修改",
|
||||
component: Edit
|
||||
},
|
||||
{
|
||||
key: "excel",
|
||||
content: rendContent("excel"),
|
||||
|
Loading…
x
Reference in New Issue
Block a user