refactor: ♻️ 规整CURD组件
This commit is contained in:
@@ -472,160 +472,22 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import ExcelJS from "exceljs";
|
||||
import { ref, reactive } from "vue";
|
||||
import { useDateFormat, useThrottleFn } from "@vueuse/core";
|
||||
import { hasAuth } from "@/plugins/permission";
|
||||
import SvgIcon from "@/components/SvgIcon/index.vue";
|
||||
import { hasAuth } from "@/plugins/permission";
|
||||
import { useDateFormat, useThrottleFn } from "@vueuse/core";
|
||||
import {
|
||||
type TableProps,
|
||||
type PaginationProps,
|
||||
genFileId,
|
||||
type FormInstance,
|
||||
type FormRules,
|
||||
type UploadInstance,
|
||||
type UploadUserFile,
|
||||
type UploadRawFile,
|
||||
genFileId,
|
||||
type UploadUserFile,
|
||||
} from "element-plus";
|
||||
import ExcelJS from "exceljs";
|
||||
import { reactive, ref } from "vue";
|
||||
import type { IContentConfig, IObject, IOperatData } from "./types";
|
||||
|
||||
// 对象类型
|
||||
export type IObject = Record<string, any>;
|
||||
// 定义接收的属性
|
||||
export interface IOperatData {
|
||||
name: string;
|
||||
row: any;
|
||||
column: any;
|
||||
$index: number;
|
||||
}
|
||||
export interface IContentConfig<T = any> {
|
||||
// 页面名称(参与组成权限标识,如sys:user:xxx)
|
||||
pageName: string;
|
||||
// table组件属性
|
||||
table?: Omit<TableProps<any>, "data">;
|
||||
// pagination组件属性
|
||||
pagination?:
|
||||
| boolean
|
||||
| Partial<
|
||||
Omit<
|
||||
PaginationProps,
|
||||
"v-model:page-size" | "v-model:current-page" | "total" | "currentPage"
|
||||
>
|
||||
>;
|
||||
// 列表的网络请求函数(需返回promise)
|
||||
indexAction: (queryParams: T) => Promise<any>;
|
||||
// 默认的分页相关的请求参数
|
||||
request?: {
|
||||
pageName: string;
|
||||
limitName: string;
|
||||
};
|
||||
// 数据格式解析的回调函数
|
||||
parseData?: (res: any) => {
|
||||
total: number;
|
||||
list: IObject[];
|
||||
[key: string]: any;
|
||||
};
|
||||
// 修改属性的网络请求函数(需返回promise)
|
||||
modifyAction?: (data: {
|
||||
[key: string]: any;
|
||||
field: string;
|
||||
value: boolean | string | number;
|
||||
}) => Promise<any>;
|
||||
// 删除的网络请求函数(需返回promise)
|
||||
deleteAction?: (ids: string) => Promise<any>;
|
||||
// 后端导出的网络请求函数(需返回promise)
|
||||
exportAction?: (queryParams: T) => Promise<any>;
|
||||
// 前端全量导出的网络请求函数(需返回promise)
|
||||
exportsAction?: (queryParams: T) => Promise<IObject[]>;
|
||||
// 前端导入模板
|
||||
importsTemplate?: string | (() => Promise<any>);
|
||||
// 前端导入的网络请求函数(需返回promise)
|
||||
importsAction?: (data: IObject[]) => Promise<any>;
|
||||
// 主键名(默认为id)
|
||||
pk?: string;
|
||||
// 表格工具栏(默认支持add,delete,export,也可自定义)
|
||||
toolbar?: Array<
|
||||
| "add"
|
||||
| "delete"
|
||||
| "export"
|
||||
| {
|
||||
auth: string;
|
||||
icon?: string;
|
||||
name: string;
|
||||
text: string;
|
||||
}
|
||||
>;
|
||||
// 表格工具栏右侧图标
|
||||
defaultToolbar?: Array<
|
||||
| "refresh"
|
||||
| "filter"
|
||||
| "imports"
|
||||
| "exports"
|
||||
| "search"
|
||||
| {
|
||||
name: string;
|
||||
icon: string;
|
||||
title?: string;
|
||||
auth?: string;
|
||||
}
|
||||
>;
|
||||
// table组件列属性(额外的属性templet,operat,slotName)
|
||||
cols: Array<{
|
||||
type?: "default" | "selection" | "index" | "expand";
|
||||
label?: string;
|
||||
prop?: string;
|
||||
width?: string | number;
|
||||
align?: "left" | "center" | "right";
|
||||
columnKey?: string;
|
||||
reserveSelection?: boolean;
|
||||
// 列是否显示
|
||||
show?: boolean;
|
||||
// 模板
|
||||
templet?:
|
||||
| "image"
|
||||
| "list"
|
||||
| "url"
|
||||
| "switch"
|
||||
| "input"
|
||||
| "price"
|
||||
| "percent"
|
||||
| "icon"
|
||||
| "date"
|
||||
| "tool"
|
||||
| "custom";
|
||||
// image模板相关参数
|
||||
imageWidth?: number;
|
||||
imageHeight?: number;
|
||||
// list模板相关参数
|
||||
selectList?: Record<string, any>;
|
||||
// switch模板相关参数
|
||||
activeValue?: boolean | string | number;
|
||||
inactiveValue?: boolean | string | number;
|
||||
activeText?: string;
|
||||
inactiveText?: string;
|
||||
// input模板相关参数
|
||||
inputType?: string;
|
||||
// price模板相关参数
|
||||
priceFormat?: string;
|
||||
// date模板相关参数
|
||||
dateFormat?: string;
|
||||
// tool模板相关参数
|
||||
operat?: Array<
|
||||
| "edit"
|
||||
| "delete"
|
||||
| {
|
||||
auth: string;
|
||||
icon?: string;
|
||||
name: string;
|
||||
text: string;
|
||||
}
|
||||
>;
|
||||
// filter值拼接符
|
||||
filterJoin?: string;
|
||||
[key: string]: any;
|
||||
// 初始化数据函数
|
||||
initFn?: (item: IObject) => void;
|
||||
}>;
|
||||
}
|
||||
const props = defineProps<{
|
||||
contentConfig: IContentConfig;
|
||||
}>();
|
||||
@@ -676,8 +538,6 @@ const cols = ref(
|
||||
);
|
||||
// 加载状态
|
||||
const loading = ref(false);
|
||||
// 删除ID集合 用于批量删除
|
||||
const removeIds = ref<(number | string)[]>([]);
|
||||
// 列表数据
|
||||
const pageData = ref<IObject[]>([]);
|
||||
// 显示分页
|
||||
@@ -704,14 +564,18 @@ const request = props.contentConfig.request ?? {
|
||||
|
||||
// 行选中
|
||||
const selectionData = ref<IObject[]>([]);
|
||||
// 删除ID集合 用于批量删除
|
||||
const removeIds = ref<(number | string)[]>([]);
|
||||
function handleSelectionChange(selection: any[]) {
|
||||
selectionData.value = selection;
|
||||
removeIds.value = selection.map((item) => item[pk]);
|
||||
}
|
||||
|
||||
// 刷新
|
||||
function handleRefresh() {
|
||||
fetchPageData(lastFormData);
|
||||
}
|
||||
|
||||
// 删除
|
||||
function handleDelete(id?: number | string) {
|
||||
const ids = [id || removeIds.value].join(",");
|
||||
@@ -735,6 +599,7 @@ function handleDelete(id?: number | string) {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 导出表单
|
||||
const fields: string[] = [];
|
||||
cols.value.forEach((item) => {
|
||||
@@ -825,6 +690,7 @@ function handleExports() {
|
||||
.catch((error) => console.log(error));
|
||||
}
|
||||
}
|
||||
|
||||
// 导入表单
|
||||
const uploadRef = ref<UploadInstance>();
|
||||
const importsModalVisible = ref(false);
|
||||
@@ -943,6 +809,7 @@ function handleImports() {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// 操作栏
|
||||
function handleToolbar(name: string) {
|
||||
switch (name) {
|
||||
@@ -972,6 +839,7 @@ function handleToolbar(name: string) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 操作列
|
||||
function handleOperat(data: IOperatData) {
|
||||
switch (data.name) {
|
||||
@@ -986,6 +854,7 @@ function handleOperat(data: IOperatData) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 属性修改
|
||||
function handleModify(
|
||||
field: string,
|
||||
@@ -1002,6 +871,7 @@ function handleModify(
|
||||
ElMessage.error("未配置modifyAction");
|
||||
}
|
||||
}
|
||||
|
||||
// 分页切换
|
||||
function handleSizeChange(value: number) {
|
||||
pagination.pageSize = value;
|
||||
@@ -1011,6 +881,7 @@ function handleCurrentChange(value: number) {
|
||||
pagination.currentPage = value;
|
||||
fetchPageData(lastFormData);
|
||||
}
|
||||
|
||||
// 远程数据筛选
|
||||
let filterParams: IObject = {};
|
||||
function handleFilterChange(newFilters: any) {
|
||||
@@ -1033,6 +904,7 @@ function handleFilterChange(newFilters: any) {
|
||||
function getFilterParams() {
|
||||
return filterParams;
|
||||
}
|
||||
|
||||
// 获取分页数据
|
||||
let lastFormData = {};
|
||||
function fetchPageData(formData: IObject = {}, isRestart = false) {
|
||||
@@ -1069,6 +941,7 @@ function fetchPageData(formData: IObject = {}, isRestart = false) {
|
||||
});
|
||||
}
|
||||
fetchPageData();
|
||||
|
||||
// 导出Excel
|
||||
function exportPageData(formData: IObject = {}) {
|
||||
if (props.contentConfig.exportAction) {
|
||||
@@ -1083,6 +956,7 @@ function exportPageData(formData: IObject = {}) {
|
||||
ElMessage.error("未配置exportAction");
|
||||
}
|
||||
}
|
||||
|
||||
// 浏览器保存文件
|
||||
function saveXlsx(fileData: BlobPart, fileName: string) {
|
||||
const fileType =
|
||||
@@ -85,22 +85,12 @@
|
||||
<script setup lang="ts">
|
||||
import type { FormInstance, FormRules } from "element-plus";
|
||||
import { reactive, ref, watch, computed, watchEffect } from "vue";
|
||||
import { IForm, IFormItems, IObject } from "./types";
|
||||
import { IPageForm, IObject } from "./types";
|
||||
|
||||
// 定义接收的属性
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
// 主键名(主要用于编辑数据,默认为id)
|
||||
pk?: string;
|
||||
// form组件属性
|
||||
form?: IForm;
|
||||
// 表单项
|
||||
formItems: IFormItems;
|
||||
}>(),
|
||||
{
|
||||
pk: "id",
|
||||
}
|
||||
);
|
||||
const props = withDefaults(defineProps<IPageForm>(), {
|
||||
pk: "id",
|
||||
});
|
||||
|
||||
const formRef = ref<FormInstance>();
|
||||
const formItems = reactive(props.formItems);
|
||||
@@ -244,83 +244,12 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type {
|
||||
FormInstance,
|
||||
FormRules,
|
||||
FormItemRule,
|
||||
FormProps,
|
||||
DialogProps,
|
||||
DrawerProps,
|
||||
} from "element-plus";
|
||||
import { useThrottleFn } from "@vueuse/core";
|
||||
import { reactive, ref, watch, watchEffect, nextTick } from "vue";
|
||||
import type { FormInstance, FormRules } from "element-plus";
|
||||
import { nextTick, reactive, ref, watch, watchEffect } from "vue";
|
||||
import type { IModalConfig, IObject } from "./types";
|
||||
|
||||
// 对象类型
|
||||
export type IObject = Record<string, any>;
|
||||
// 定义接收的属性
|
||||
export interface IModalConfig<T = any> {
|
||||
// 页面名称
|
||||
pageName?: string;
|
||||
// 主键名(主要用于编辑数据,默认为id)
|
||||
pk?: string;
|
||||
// 组件类型
|
||||
component?: "dialog" | "drawer";
|
||||
// dialog组件属性
|
||||
dialog?: Partial<Omit<DialogProps, "modelValue">>;
|
||||
// drawer组件属性
|
||||
drawer?: Partial<Omit<DrawerProps, "modelValue">>;
|
||||
// form组件属性
|
||||
form?: Partial<Omit<FormProps, "model" | "rules">>;
|
||||
// 表单项
|
||||
formItems: Array<{
|
||||
// 组件类型(如input,select,radio,custom等,默认input)
|
||||
type?:
|
||||
| "input"
|
||||
| "select"
|
||||
| "radio"
|
||||
| "checkbox"
|
||||
| "tree-select"
|
||||
| "date-picker"
|
||||
| "input-number"
|
||||
| "text"
|
||||
| "custom";
|
||||
// 组件属性
|
||||
attrs?: IObject;
|
||||
// 组件可选项(适用于select,radio,checkbox组件)
|
||||
options?: Array<{
|
||||
label: string;
|
||||
value: any;
|
||||
disabled?: boolean;
|
||||
[key: string]: any;
|
||||
}>;
|
||||
// 插槽名(适用于组件类型为custom)
|
||||
slotName?: string;
|
||||
// 标签文本
|
||||
label: string;
|
||||
// 标签提示
|
||||
tips?: string;
|
||||
// 键名
|
||||
prop: string;
|
||||
// 验证规则
|
||||
rules?: FormItemRule[];
|
||||
// 初始值
|
||||
initialValue?: any;
|
||||
// 是否隐藏
|
||||
hidden?: boolean;
|
||||
// 监听函数
|
||||
watch?: (newValue: any, oldValue: any, data: T, items: IObject[]) => void;
|
||||
// 计算属性函数
|
||||
computed?: (data: T) => any;
|
||||
// 监听收集函数
|
||||
watchEffect?: (data: T) => void;
|
||||
// 初始化数据函数扩展
|
||||
initFn?: (item: IObject) => void;
|
||||
}>;
|
||||
// 提交之前处理
|
||||
beforeSubmit?: (data: T) => void;
|
||||
// 提交的网络请求函数(需返回promise)
|
||||
formAction: (data: T) => Promise<any>;
|
||||
}
|
||||
const props = defineProps<{
|
||||
modalConfig: IModalConfig;
|
||||
}>();
|
||||
@@ -336,6 +265,7 @@ const formItems = reactive(props.modalConfig.formItems);
|
||||
const formData = reactive<IObject>({});
|
||||
const formRules: FormRules = {};
|
||||
const prepareFuncs = [];
|
||||
|
||||
// 初始化
|
||||
for (const item of formItems) {
|
||||
item.initFn && item.initFn(item);
|
||||
@@ -396,6 +326,7 @@ const handleSubmit = useThrottleFn(() => {
|
||||
}
|
||||
});
|
||||
}, 3000);
|
||||
|
||||
// 关闭弹窗
|
||||
function handleCloseModal() {
|
||||
modalVisible.value = false;
|
||||
@@ -404,6 +335,7 @@ function handleCloseModal() {
|
||||
formRef.value?.clearValidate();
|
||||
});
|
||||
}
|
||||
|
||||
// 显示modal
|
||||
function setModalVisible(data: IObject = {}) {
|
||||
modalVisible.value = true;
|
||||
@@ -412,10 +344,12 @@ function setModalVisible(data: IObject = {}) {
|
||||
Object.values(data).length > 0 && setFormData(data);
|
||||
});
|
||||
}
|
||||
|
||||
// 获取表单数据
|
||||
function getFormData(key?: string) {
|
||||
return key === undefined ? formData : formData[key] ?? undefined;
|
||||
}
|
||||
|
||||
// 设置表单值
|
||||
function setFormData(data: IObject) {
|
||||
for (const key in formData) {
|
||||
@@ -427,6 +361,7 @@ function setFormData(data: IObject) {
|
||||
formData[pk] = data[pk];
|
||||
}
|
||||
}
|
||||
|
||||
// 设置表单项值
|
||||
function setFormItemData(key: string, value: any) {
|
||||
formData[key] = value;
|
||||
@@ -116,42 +116,12 @@
|
||||
<script setup lang="ts">
|
||||
import type { FormInstance } from "element-plus";
|
||||
import { reactive, ref } from "vue";
|
||||
import type { IObject, ISearchConfig } from "./types";
|
||||
|
||||
// 对象类型
|
||||
type IObject = Record<string, any>;
|
||||
// 定义接收的属性
|
||||
export interface ISearchConfig {
|
||||
// 页面名称(参与组成权限标识,如sys:user:xxx)
|
||||
pageName: string;
|
||||
// 表单项
|
||||
formItems: Array<{
|
||||
// 组件类型(如input,select等)
|
||||
type?: "input" | "select" | "tree-select" | "date-picker" | "input-tag";
|
||||
// 标签文本
|
||||
label: string;
|
||||
// 标签提示
|
||||
tips?: string;
|
||||
// 键名
|
||||
prop: string;
|
||||
// 组件属性(input-tag组件支持join,btnText,size属性)
|
||||
attrs?: IObject;
|
||||
// 初始值
|
||||
initialValue?: any;
|
||||
// 可选项(适用于select组件)
|
||||
options?: { label: string; value: any }[];
|
||||
// 初始化数据函数扩展
|
||||
initFn?: (formItem: IObject) => void;
|
||||
}>;
|
||||
// 是否开启展开和收缩
|
||||
isExpandable?: boolean;
|
||||
// 默认展示的表单项数量
|
||||
showNumber?: number;
|
||||
}
|
||||
|
||||
interface IProps {
|
||||
const props = defineProps<{
|
||||
searchConfig: ISearchConfig;
|
||||
}
|
||||
const props = defineProps<IProps>();
|
||||
}>();
|
||||
// 自定义事件
|
||||
const emit = defineEmits<{
|
||||
queryClick: [queryParams: IObject];
|
||||
@@ -218,23 +188,28 @@ for (const item of formItems) {
|
||||
queryParams[item.prop] = item.initialValue ?? "";
|
||||
}
|
||||
}
|
||||
|
||||
// 重置操作
|
||||
function handleReset() {
|
||||
queryFormRef.value?.resetFields();
|
||||
emit("resetClick", queryParams);
|
||||
}
|
||||
|
||||
// 查询操作
|
||||
function handleQuery() {
|
||||
emit("queryClick", queryParams);
|
||||
}
|
||||
|
||||
// 获取分页数据
|
||||
function getQueryParams() {
|
||||
return queryParams;
|
||||
}
|
||||
|
||||
// 显示/隐藏 SearchForm
|
||||
function toggleVisible() {
|
||||
visible.value = !visible.value;
|
||||
}
|
||||
|
||||
// 关闭标签
|
||||
function handleCloseTag(prop: string, tag: string) {
|
||||
inputTagMap[prop].data.splice(inputTagMap[prop].data.indexOf(tag), 1);
|
||||
262
src/components/CURD/types.ts
Normal file
262
src/components/CURD/types.ts
Normal file
@@ -0,0 +1,262 @@
|
||||
import type {
|
||||
DialogProps,
|
||||
DrawerProps,
|
||||
FormItemRule,
|
||||
FormProps,
|
||||
PaginationProps,
|
||||
TableProps,
|
||||
} from "element-plus";
|
||||
import PageContent from "./PageContent.vue";
|
||||
import PageForm from "./PageForm.vue";
|
||||
import PageModal from "./PageModal.vue";
|
||||
import PageSearch from "./PageSearch.vue";
|
||||
|
||||
export type PageSearchInstance = InstanceType<typeof PageSearch>;
|
||||
export type PageContentInstance = InstanceType<typeof PageContent>;
|
||||
export type PageModalInstance = InstanceType<typeof PageModal>;
|
||||
export type PageFormInstance = InstanceType<typeof PageForm>;
|
||||
|
||||
export type IObject = Record<string, any>;
|
||||
|
||||
export interface IOperatData {
|
||||
name: string;
|
||||
row: any;
|
||||
column: any;
|
||||
$index: number;
|
||||
}
|
||||
|
||||
export interface ISearchConfig {
|
||||
// 页面名称(参与组成权限标识,如sys:user:xxx)
|
||||
pageName: string;
|
||||
// 表单项
|
||||
formItems: Array<{
|
||||
// 组件类型(如input,select等)
|
||||
type?: "input" | "select" | "tree-select" | "date-picker" | "input-tag";
|
||||
// 标签文本
|
||||
label: string;
|
||||
// 标签提示
|
||||
tips?: string;
|
||||
// 键名
|
||||
prop: string;
|
||||
// 组件属性(input-tag组件支持join,btnText,size属性)
|
||||
attrs?: IObject;
|
||||
// 初始值
|
||||
initialValue?: any;
|
||||
// 可选项(适用于select组件)
|
||||
options?: { label: string; value: any }[];
|
||||
// 初始化数据函数扩展
|
||||
initFn?: (formItem: IObject) => void;
|
||||
}>;
|
||||
// 是否开启展开和收缩
|
||||
isExpandable?: boolean;
|
||||
// 默认展示的表单项数量
|
||||
showNumber?: number;
|
||||
}
|
||||
|
||||
export interface IContentConfig<T = any> {
|
||||
// 页面名称(参与组成权限标识,如sys:user:xxx)
|
||||
pageName: string;
|
||||
// table组件属性
|
||||
table?: Omit<TableProps<any>, "data">;
|
||||
// pagination组件属性
|
||||
pagination?:
|
||||
| boolean
|
||||
| Partial<
|
||||
Omit<
|
||||
PaginationProps,
|
||||
"v-model:page-size" | "v-model:current-page" | "total" | "currentPage"
|
||||
>
|
||||
>;
|
||||
// 列表的网络请求函数(需返回promise)
|
||||
indexAction: (queryParams: T) => Promise<any>;
|
||||
// 默认的分页相关的请求参数
|
||||
request?: {
|
||||
pageName: string;
|
||||
limitName: string;
|
||||
};
|
||||
// 数据格式解析的回调函数
|
||||
parseData?: (res: any) => {
|
||||
total: number;
|
||||
list: IObject[];
|
||||
[key: string]: any;
|
||||
};
|
||||
// 修改属性的网络请求函数(需返回promise)
|
||||
modifyAction?: (data: {
|
||||
[key: string]: any;
|
||||
field: string;
|
||||
value: boolean | string | number;
|
||||
}) => Promise<any>;
|
||||
// 删除的网络请求函数(需返回promise)
|
||||
deleteAction?: (ids: string) => Promise<any>;
|
||||
// 后端导出的网络请求函数(需返回promise)
|
||||
exportAction?: (queryParams: T) => Promise<any>;
|
||||
// 前端全量导出的网络请求函数(需返回promise)
|
||||
exportsAction?: (queryParams: T) => Promise<IObject[]>;
|
||||
// 前端导入模板
|
||||
importsTemplate?: string | (() => Promise<any>);
|
||||
// 前端导入的网络请求函数(需返回promise)
|
||||
importsAction?: (data: IObject[]) => Promise<any>;
|
||||
// 主键名(默认为id)
|
||||
pk?: string;
|
||||
// 表格工具栏(默认支持add,delete,export,也可自定义)
|
||||
toolbar?: Array<
|
||||
| "add"
|
||||
| "delete"
|
||||
| "export"
|
||||
| {
|
||||
auth: string;
|
||||
icon?: string;
|
||||
name: string;
|
||||
text: string;
|
||||
}
|
||||
>;
|
||||
// 表格工具栏右侧图标
|
||||
defaultToolbar?: Array<
|
||||
| "refresh"
|
||||
| "filter"
|
||||
| "imports"
|
||||
| "exports"
|
||||
| "search"
|
||||
| {
|
||||
name: string;
|
||||
icon: string;
|
||||
title?: string;
|
||||
auth?: string;
|
||||
}
|
||||
>;
|
||||
// table组件列属性(额外的属性templet,operat,slotName)
|
||||
cols: Array<{
|
||||
type?: "default" | "selection" | "index" | "expand";
|
||||
label?: string;
|
||||
prop?: string;
|
||||
width?: string | number;
|
||||
align?: "left" | "center" | "right";
|
||||
columnKey?: string;
|
||||
reserveSelection?: boolean;
|
||||
// 列是否显示
|
||||
show?: boolean;
|
||||
// 模板
|
||||
templet?:
|
||||
| "image"
|
||||
| "list"
|
||||
| "url"
|
||||
| "switch"
|
||||
| "input"
|
||||
| "price"
|
||||
| "percent"
|
||||
| "icon"
|
||||
| "date"
|
||||
| "tool"
|
||||
| "custom";
|
||||
// image模板相关参数
|
||||
imageWidth?: number;
|
||||
imageHeight?: number;
|
||||
// list模板相关参数
|
||||
selectList?: Record<string, any>;
|
||||
// switch模板相关参数
|
||||
activeValue?: boolean | string | number;
|
||||
inactiveValue?: boolean | string | number;
|
||||
activeText?: string;
|
||||
inactiveText?: string;
|
||||
// input模板相关参数
|
||||
inputType?: string;
|
||||
// price模板相关参数
|
||||
priceFormat?: string;
|
||||
// date模板相关参数
|
||||
dateFormat?: string;
|
||||
// tool模板相关参数
|
||||
operat?: Array<
|
||||
| "edit"
|
||||
| "delete"
|
||||
| {
|
||||
auth: string;
|
||||
icon?: string;
|
||||
name: string;
|
||||
text: string;
|
||||
}
|
||||
>;
|
||||
// filter值拼接符
|
||||
filterJoin?: string;
|
||||
[key: string]: any;
|
||||
// 初始化数据函数
|
||||
initFn?: (item: IObject) => void;
|
||||
}>;
|
||||
}
|
||||
|
||||
export interface IModalConfig<T = any> {
|
||||
// 页面名称
|
||||
pageName?: string;
|
||||
// 主键名(主要用于编辑数据,默认为id)
|
||||
pk?: string;
|
||||
// 组件类型
|
||||
component?: "dialog" | "drawer";
|
||||
// dialog组件属性
|
||||
dialog?: Partial<Omit<DialogProps, "modelValue">>;
|
||||
// drawer组件属性
|
||||
drawer?: Partial<Omit<DrawerProps, "modelValue">>;
|
||||
// form组件属性
|
||||
form?: IForm;
|
||||
// 表单项
|
||||
formItems: IFormItems<T>;
|
||||
// 提交之前处理
|
||||
beforeSubmit?: (data: T) => void;
|
||||
// 提交的网络请求函数(需返回promise)
|
||||
formAction: (data: T) => Promise<any>;
|
||||
}
|
||||
|
||||
export type IForm = Partial<Omit<FormProps, "model" | "rules">>;
|
||||
|
||||
// 表单项
|
||||
export type IFormItems<T = any> = Array<{
|
||||
// 组件类型(如input,select,radio,custom等,默认input)
|
||||
type?:
|
||||
| "input"
|
||||
| "select"
|
||||
| "radio"
|
||||
| "checkbox"
|
||||
| "tree-select"
|
||||
| "date-picker"
|
||||
| "input-number"
|
||||
| "text"
|
||||
| "custom";
|
||||
// 组件属性
|
||||
attrs?: IObject;
|
||||
// 组件可选项(适用于select,radio,checkbox组件)
|
||||
options?: Array<{
|
||||
label: string;
|
||||
value: any;
|
||||
disabled?: boolean;
|
||||
[key: string]: any;
|
||||
}>;
|
||||
// 插槽名(适用于组件类型为custom)
|
||||
slotName?: string;
|
||||
// 标签文本
|
||||
label: string;
|
||||
// 标签提示
|
||||
tips?: string;
|
||||
// 键名
|
||||
prop: string;
|
||||
// 验证规则
|
||||
rules?: FormItemRule[];
|
||||
// 初始值
|
||||
initialValue?: any;
|
||||
// 是否隐藏
|
||||
hidden?: boolean;
|
||||
// 监听函数
|
||||
watch?: (newValue: any, oldValue: any, data: T, items: IObject[]) => void;
|
||||
// 计算属性函数
|
||||
computed?: (data: T) => any;
|
||||
// 监听收集函数
|
||||
watchEffect?: (data: T) => void;
|
||||
// 初始化数据函数扩展
|
||||
initFn?: (item: IObject) => void;
|
||||
}>;
|
||||
|
||||
export interface IPageForm {
|
||||
// 主键名(主要用于编辑数据,默认为id)
|
||||
pk?: string;
|
||||
// form组件属性
|
||||
form?: IForm;
|
||||
// 表单项
|
||||
formItems: IFormItems;
|
||||
}
|
||||
73
src/components/CURD/usePage.ts
Normal file
73
src/components/CURD/usePage.ts
Normal file
@@ -0,0 +1,73 @@
|
||||
import { ref } from "vue";
|
||||
import type {
|
||||
IObject,
|
||||
PageContentInstance,
|
||||
PageModalInstance,
|
||||
PageSearchInstance,
|
||||
} from "./types";
|
||||
|
||||
function usePage() {
|
||||
const searchRef = ref<PageSearchInstance>();
|
||||
const contentRef = ref<PageContentInstance>();
|
||||
const addModalRef = ref<PageModalInstance>();
|
||||
const editModalRef = ref<PageModalInstance>();
|
||||
|
||||
// 搜索
|
||||
function handleQueryClick(queryParams: IObject) {
|
||||
const filterParams = contentRef.value?.getFilterParams();
|
||||
contentRef.value?.fetchPageData({ ...queryParams, ...filterParams }, true);
|
||||
}
|
||||
// 重置
|
||||
function handleResetClick(queryParams: IObject) {
|
||||
const filterParams = contentRef.value?.getFilterParams();
|
||||
contentRef.value?.fetchPageData({ ...queryParams, ...filterParams }, true);
|
||||
}
|
||||
// 新增
|
||||
function handleAddClick() {
|
||||
//显示添加表单
|
||||
addModalRef.value?.setModalVisible();
|
||||
}
|
||||
// 编辑
|
||||
function handleEditClick(row: IObject) {
|
||||
//显示编辑表单 根据数据进行填充
|
||||
editModalRef.value?.setModalVisible(row);
|
||||
}
|
||||
// 表单提交
|
||||
function handleSubmitClick() {
|
||||
//根据检索条件刷新列表数据
|
||||
const queryParams = searchRef.value?.getQueryParams();
|
||||
contentRef.value?.fetchPageData(queryParams, true);
|
||||
}
|
||||
// 导出
|
||||
function handleExportClick() {
|
||||
// 根据检索条件导出数据
|
||||
const queryParams = searchRef.value?.getQueryParams();
|
||||
contentRef.value?.exportPageData(queryParams);
|
||||
}
|
||||
// 搜索显隐
|
||||
function handleSearchClick() {
|
||||
searchRef.value?.toggleVisible();
|
||||
}
|
||||
// 涮选数据
|
||||
function handleFilterChange(filterParams: IObject) {
|
||||
const queryParams = searchRef.value?.getQueryParams();
|
||||
contentRef.value?.fetchPageData({ ...queryParams, ...filterParams }, true);
|
||||
}
|
||||
|
||||
return {
|
||||
searchRef,
|
||||
contentRef,
|
||||
addModalRef,
|
||||
editModalRef,
|
||||
handleQueryClick,
|
||||
handleResetClick,
|
||||
handleAddClick,
|
||||
handleEditClick,
|
||||
handleSubmitClick,
|
||||
handleExportClick,
|
||||
handleSearchClick,
|
||||
handleFilterChange,
|
||||
};
|
||||
}
|
||||
|
||||
export default usePage;
|
||||
@@ -1,64 +0,0 @@
|
||||
import type {
|
||||
DialogProps,
|
||||
DrawerProps,
|
||||
FormProps,
|
||||
FormItemRule,
|
||||
} from "element-plus";
|
||||
|
||||
// dialog组件属性
|
||||
export type IDialog = Partial<Omit<DialogProps, "modelValue">>;
|
||||
|
||||
// drawer组件属性
|
||||
export type IDrawer = Partial<Omit<DrawerProps, "modelValue">>;
|
||||
|
||||
// form组件属性
|
||||
export type IForm = Partial<Omit<FormProps, "model" | "rules">>;
|
||||
|
||||
// 对象类型
|
||||
export type IObject = Record<string, any>;
|
||||
|
||||
// 表单项
|
||||
export type IFormItems<T = any> = Array<{
|
||||
// 组件类型(如input,select,radio,custom等,默认input)
|
||||
type?:
|
||||
| "input"
|
||||
| "select"
|
||||
| "radio"
|
||||
| "checkbox"
|
||||
| "tree-select"
|
||||
| "date-picker"
|
||||
| "input-number"
|
||||
| "text"
|
||||
| "custom";
|
||||
// 组件属性
|
||||
attrs?: IObject;
|
||||
// 组件可选项(适用于select,radio,checkbox组件)
|
||||
options?: Array<{
|
||||
label: string;
|
||||
value: any;
|
||||
disabled?: boolean;
|
||||
[key: string]: any;
|
||||
}>;
|
||||
// 插槽名(适用于组件类型为custom)
|
||||
slotName?: string;
|
||||
// 标签文本
|
||||
label: string;
|
||||
// 标签提示
|
||||
tips?: string;
|
||||
// 键名
|
||||
prop: string;
|
||||
// 验证规则
|
||||
rules?: FormItemRule[];
|
||||
// 初始值
|
||||
initialValue?: any;
|
||||
// 是否隐藏
|
||||
hidden?: boolean;
|
||||
// 监听函数
|
||||
watch?: (newValue: any, oldValue: any, data: T, items: IObject[]) => void;
|
||||
// 计算属性函数
|
||||
computed?: (data: T) => any;
|
||||
// 监听收集函数
|
||||
watchEffect?: (data: T) => void;
|
||||
// 初始化数据函数扩展
|
||||
initFn?: (item: IObject) => void;
|
||||
}>;
|
||||
Reference in New Issue
Block a user