refactor: ♻️ 抽离CURD的使用部分代码为Hooks实现

This commit is contained in:
cshaptx4869
2024-04-27 20:22:23 +08:00
parent b9a4890354
commit 1e0dee0a6e
5 changed files with 140 additions and 50 deletions

View File

@@ -144,6 +144,18 @@ export default defineMock([
};
},
},
// 导出Excel
{
url: "users/_export",
method: ["GET"],
headers: {
"Content-Disposition":
"attachment; filename=%E7%94%A8%E6%88%B7%E5%88%97%E8%A1%A8.xlsx",
"Content-Type":
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
},
},
]);
// 用户映射表数据

View File

@@ -185,7 +185,7 @@ import Pagination from "@/components/Pagination/index.vue";
import type { TableProps } from "element-plus";
// 对象类型
type IObject = Record<string, any>;
export type IObject = Record<string, any>;
// 定义接收的属性
export interface IOperatData {
name: string;
@@ -201,7 +201,9 @@ export interface IContentConfig {
// 列表的网络请求函数(需返回promise)
indexAction: (data: IObject) => Promise<IObject>;
// 删除的网络请求函数(需返回promise)
deleteAction: (id: string) => Promise<any>;
deleteAction?: (id: string) => Promise<any>;
// 导出的网络请求函数(需返回promise)
exportAction?: (queryParams: IObject) => Promise<any>;
// 主键名(默认为id)
pk?: string;
// 表格工具栏(默认支持refresh,add,delete,export,也可自定义)
@@ -232,7 +234,7 @@ const emit = defineEmits<{
operatClick: [data: IOperatData];
}>();
// 暴露的属性和方法
defineExpose({ fetchPageData });
defineExpose({ fetchPageData, exportPageData });
// 主键
const pk = props.contentConfig.pk ?? "id";
@@ -294,10 +296,14 @@ function handleDelete(id?: number | string) {
cancelButtonText: "取消",
type: "warning",
}).then(function () {
props.contentConfig.deleteAction(ids).then(() => {
ElMessage.success("删除成功");
handleRefresh();
});
if (props.contentConfig.deleteAction) {
props.contentConfig.deleteAction(ids).then(() => {
ElMessage.success("删除成功");
handleRefresh();
});
} else {
ElMessage.error("未配置deleteAction");
}
});
}
// 分页
@@ -338,6 +344,31 @@ function handleOperat(data: IOperatData) {
break;
}
}
// 导出Excel
function exportPageData(queryParams: IObject = {}) {
if (props.contentConfig.exportAction) {
props.contentConfig.exportAction(queryParams).then((response) => {
const fileData = response.data;
const fileName = decodeURI(
response.headers["content-disposition"].split(";")[1].split("=")[1]
);
const fileType =
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8";
const blob = new Blob([fileData], { type: fileType });
const downloadUrl = window.URL.createObjectURL(blob);
const downloadLink = document.createElement("a");
downloadLink.href = downloadUrl;
downloadLink.download = fileName;
document.body.appendChild(downloadLink);
downloadLink.click();
document.body.removeChild(downloadLink);
window.URL.revokeObjectURL(downloadUrl);
});
} else {
ElMessage.error("未配置exportAction");
}
}
</script>
<style lang="scss" scoped></style>

58
src/hooks/usePage.ts Normal file
View File

@@ -0,0 +1,58 @@
import { ref } from "vue";
import type PageSearch from "@/components/PageSearch/index.vue";
import type PageContent from "@/components/PageContent/index.vue";
import type PageModal from "@/components/PageModal/index.vue";
import type { IOperatData, IObject } from "@/components/PageContent/index.vue";
export type { IOperatData, IObject };
function usePage() {
const searchRef = ref<InstanceType<typeof PageSearch>>();
const contentRef = ref<InstanceType<typeof PageContent>>();
const addModalRef = ref<InstanceType<typeof PageModal>>();
const editModalRef = ref<InstanceType<typeof PageModal>>();
// 搜索
function handleQueryClick(queryParams: IObject) {
contentRef.value?.fetchPageData(queryParams, true);
}
// 重置
function handleResetClick() {
contentRef.value?.fetchPageData({}, true);
}
// 新增
function handleAddClick() {
//显示添加表单
addModalRef.value?.setModalVisible();
}
// 编辑
function handleEditClick(row: IObject) {
//显示编辑表单 根据数据进行填充
editModalRef.value?.setModalVisible(row);
}
// 表单提交
function handleSubmitClick() {
//刷新列表数据
contentRef.value?.fetchPageData({}, true);
}
// 导出
function handleExportClick() {
// 根据检索条件导出数据
const queryParams = searchRef.value?.getQueryParams();
contentRef.value?.exportPageData(queryParams);
}
return {
searchRef,
contentRef,
addModalRef,
editModalRef,
handleQueryClick,
handleResetClick,
handleAddClick,
handleEditClick,
handleSubmitClick,
handleExportClick,
};
}
export default usePage;

View File

@@ -1,4 +1,5 @@
import type { IContentConfig } from "@/components/PageContent/index.vue";
import { exportUser } from "@/api/user";
const contentConfig: IContentConfig = {
pageName: "sys:user",
@@ -60,6 +61,10 @@ const contentConfig: IContentConfig = {
});
});
},
exportAction: function (queryParams) {
// 导出Excel文件
return exportUser(queryParams as any);
},
pk: "id",
toolbar: [
"refresh",

View File

@@ -19,9 +19,9 @@
@operat-click="handleOperatClick"
>
<template #status="scope">
<el-tag :type="scope.row[scope.prop] == 1 ? 'success' : 'info'">{{
scope.row[scope.prop] == 1 ? "启用" : "禁用"
}}</el-tag>
<el-tag :type="scope.row[scope.prop] == 1 ? 'success' : 'info'">
{{ scope.row[scope.prop] == 1 ? "启用" : "禁用" }}
</el-tag>
</template>
</page-content>
@@ -46,43 +46,25 @@ import searchConfig from "./config/search";
import contentConfig from "./config/content";
import addModalConfig from "./config/add";
import editModalConfig from "./config/edit";
import type PageSearch from "@/components/PageSearch/index.vue";
import type PageContent from "@/components/PageContent/index.vue";
import type { IOperatData } from "@/components/PageContent/index.vue";
import type PageModal from "@/components/PageModal/index.vue";
import usePage from "@/hooks/usePage";
import type { IOperatData, IObject } from "@/hooks/usePage";
const searchRef = ref<InstanceType<typeof PageSearch>>();
const contentRef = ref<InstanceType<typeof PageContent>>();
const addModalRef = ref<InstanceType<typeof PageModal>>();
// 搜索
function handleQueryClick(queryParams: any) {
contentRef.value?.fetchPageData(queryParams, true);
}
// 重置
function handleResetClick() {
contentRef.value?.fetchPageData({}, true);
}
// 新增
function handleAddClick() {
//显示添加表单
addModalRef.value?.setModalVisible();
}
// 导出
function handleExportClick() {
console.log("export");
// 可以根据检索条件去导出数据
console.log(searchRef.value?.getQueryParams());
}
// 其他工具栏
function handleToolbarClick(name: string) {
console.log(name);
}
const {
searchRef,
contentRef,
addModalRef,
editModalRef,
handleQueryClick,
handleResetClick,
handleAddClick,
// handleEditClick,
handleSubmitClick,
handleExportClick,
} = usePage();
// 编辑
const editModalRef = ref<InstanceType<typeof PageModal>>();
function handleEditClick(row: any) {
//显示编辑表单 根据id获取的数据进行填充
const idMap: Record<string, any> = {
function handleEditClick(row: IObject) {
// 模拟根据id获取数据进行填充
const idMap: IObject = {
2: {
id: 2,
username: "admin",
@@ -112,6 +94,13 @@ function handleEditClick(row: any) {
};
editModalRef.value?.setModalVisible(idMap[row.id]);
}
// 其他工具栏
function handleToolbarClick(name: string) {
console.log(name);
if (name === "upload") {
ElMessage.success("点击了导入按钮");
}
}
// 其他操作列
function handleOperatClick(data: IOperatData) {
console.log(data);
@@ -134,9 +123,4 @@ function handleOperatClick(data: IOperatData) {
});
}
}
// 表单提交
function handleSubmitClick() {
//刷新列表数据
contentRef.value?.fetchPageData({}, true);
}
</script>