需求背景
需求:页面表格的展示字段可配置。用户修改配置后,下次再进入按照个人定义配置展示。
完成样式:
点击按钮,然后设置。
其实是类似 AntDesign 的 ProTable - 高级表格 ProTable - 高级表格
但是这里的列展示不能保存设置,刷新会重置。
现在自己写了个列设置,使用 localStorage 缓存设置。
因为原来的列展示有customRender,localStorage不能直接存方法 customRender,所以先标记,展示的时候再遍历 - findCustomRender。
(其实也可以在 localStorage 缓存每个列的列名,展示的时候遍历原列表取columns值)
实现代码如下
在 template 放个按钮,点击弹出弹窗;
a-table 设置 :columns=“filteredColumns”
<template>
<a-table
:columns="filteredColumns"
rowKey="id"
:dataSource="tableList.value"
>
<a-modal
title="列设置"
v-model:visible="isModalVisible"
@ok="handleOk"
@cancel="handleCancel"
>
<div class="checkbox-container">
<a-checkbox
v-model:checked="checkAll"
class="checkbox-container-top"
@change="onCheckAllChange"
>
全选
</a-checkbox>
<a-divider class="divider" />
<a-checkbox-group
v-model:value="selectedColumns"
class="checkbox-container-bottom"
:options="allColumnsOptions"
@change="changeCheckBox"
></a-checkbox-group>
</div>
</a-modal>
</template>
<script lang="ts" setup>
// customRender 列展示文字
const statusMap = {
0: "未确认",
1: "已确认",
3: "已归档",
4: "已作废",
};
// 定义表格 Columns列的类型,假设是这样,customRender是 string类型
interface ColumnType {
title: string;
dataIndex: string;
fixed?: "left" | "right";
width?: number;
ellipsis?: boolean;
customRender?: (params: { text: string }) => string;
}
// 列设置- allColumns 是表格Columns值, 例子:
const allColumns: ColumnType[] =[
{
title: "ID",
dataIndex: "id",
fixed: "left",
width: 70,
},
{
title: "状态",
dataIndex: "status",
width: 80,
customRender: ({ text }: { text: string }) => statusMap[text],
}]
const allColumnsOptions = ref(
allColumns.map((item: { title: string; dataIndex: string }) => ({
label: item.title,
value: item.dataIndex,
})),
);
const localStorageColumns = localStorage.getItem("saveColmuns")
const filteredColumns = ref<ColumnType[]>([]);
const selectedColumns = ref(
filteredColumns.value.map(
(col: { dataIndex: string | number }) => col.dataIndex,
),
);
const checkAll = ref(true);
// 列设置- 控制弹框的显示与隐藏
const isModalVisible = ref(false);
const showModal = () => {
isModalVisible.value = true;
selectedColumns.value = filteredColumns.value.map(
(col: { dataIndex: string }) => col.dataIndex,
);
checkAll.value =
selectedColumns.value.length === allColumns.length ? true : false;
};
const DeepStringToArray = (array: ColumnType[]) => {
return array.map((item) => ({
...item,
customRender: item.customRender ? true : undefined,
}));
};
const findCustomRender = (array: ColumnType[]) => {
return array.map((item) => {
if (item.customRender) {
item.customRender = allColumns.find(
(c) => item.dataIndex === c.dataIndex,
)?.customRender;
}
return item;
});
};
const handleOk = () => {
isModalVisible.value = false;
filteredColumns.value = allColumns.filter((col: { dataIndex: string }) =>
selectedColumns.value.includes(col.dataIndex),
);
const stringifyColumns = JSON.stringify(
DeepStringToArray(filteredColumns.value), // localStorage不能直接存方法 customRender,所以先做个标记 customRender:true
);
localStorage.setItem("saveColmuns", stringifyColumns)
};
const handleCancel = () => {
isModalVisible.value = false;
};
const onCheckAllChange = (e: { target: { checked: boolean } }) => {
checkAll.value = e?.target?.checked;
selectedColumns.value = checkAll.value
? allColumns.map((col: { dataIndex: string }) => col.dataIndex)
: [];
};
const changeCheckBox = (val: CheckboxValueType[]) => {
checkAll.value = val.length === allColumns.length ? true : false;
};
</script>
<style scoped lang="less">
// 列设置
.checkbox-container {
display: flex;
flex-direction: column;
max-height: 400px;
overflow: hidden;
.checkbox-container-top {
flex-shrink: 0;
}
.divider {
margin: 12px 0;
}
.checkbox-container-bottom {
display: flex;
flex: 1;
overflow-y: auto;
flex-direction: column;
}
}
.checkbox-item {
margin-bottom: 10px;
}
</style>