feat: 临时提交

master
luoer 2023-11-10 17:45:47 +08:00
parent 34b3a73f30
commit a2c263cef7
14 changed files with 578 additions and 142 deletions

View File

@ -1,80 +1,90 @@
import { FormItem as BaseFormItem, FieldRule, FormItemInstance, SelectOptionData } from "@arco-design/web-vue"; import { FormItem as BaseFormItem, FormItemInstance, SelectOptionData } from "@arco-design/web-vue";
import { NodeType, NodeUnion, nodeMap } from "./form-node"; import { NodeUnion, nodeMap } from "./form-node";
import { RuleMap } from "./form-rules"; import { FieldObjectRule, FieldRuleMap, Rule } from "./form-rules";
import { PropType } from "vue";
export type FieldStringRule = keyof typeof RuleMap; import { strOrFnRender } from "./util";
export type FieldObjectRule = FieldRule & {
disable?: (arg: { item: IFormItem; model: Record<string, any> }) => boolean;
};
export type FieldRuleType = FieldStringRule | FieldObjectRule;
/** /**
* *
*/ */
export const FormItem = (props: any, { emit }: any) => { export const FormItem = defineComponent({
const { item } = props; name: "AppnifyFormItem",
const args = { props: {
...props, /**
field: item.field, *
}; */
item: {
type: Object as PropType<IFormItem>,
required: true,
},
/**
*
*/
items: {
type: Array as PropType<IFormItem[]>,
required: true,
},
/**
*
*/
model: {
type: Object as PropType<Recordable>,
required: true,
},
},
setup(props) {
/**
*
*/
const rules = computed(() => props.item.rules?.filter((i) => !i.disable?.(props)));
const rules = computed(() => { /**
const result = []; *
if (item.required) { */
result.push(RuleMap.required); const disabled = computed(() => Boolean(props.item.disable?.(props)));
if (props.item.visible && !props.item.visible(props as any)) {
return null;
} }
item.rules?.forEach((rule: any) => {
if (typeof rule === "string") {
result.push(RuleMap[rule as FieldStringRule]);
return;
}
if (!rule.disable) {
result.push(rule);
return;
}
if (!rule.disable({ model: props.model, item, items: props.items })) {
result.push(rule);
}
});
return result;
});
const disabled = computed(() => { /**
if (item.disable === undefined) { *
return false; */
} const render = () => {
if (typeof item.disable === "function") { const Item = props.item.component as any;
return item.disable(args); if (props.item.type === "custom") {
} return <Item {...props.item.nodeProps} items={props.items} model={props.model} item={props.item} />;
return item.disable; }
}); return <Item {...props.item.nodeProps} v-model={props.model[props.item.field]} />;
};
if (item.visible && !item.visible(args)) { /**
return null; *
} */
const label = strOrFnRender(props.item.label, props);
return ( /**
<BaseFormItem {...item.itemProps} rules={rules.value} disabled={disabled.value} field={item.field}> *
{{ */
default: () => { const help = strOrFnRender(props.item.help, props);
if (item.component) {
return <item.component {...item.nodeProps} model={props.model} item={props.item} />; /**
} *
const comp = nodeMap[item.type as NodeType]?.component; */
if (!comp) { const extra = strOrFnRender(props.item.extra, props);
return null;
} return () => (
if (item.type === "submit") { <BaseFormItem {...props.item.itemProps} rules={rules.value} disabled={disabled.value} field={props.item.field}>
return <comp loading={props.loading} onSubmit={() => emit("submit")} onCancel={emit("cancel")} />; {{ default: render, label, help, extra }}
} </BaseFormItem>
return <comp v-model={props.model[item.field]} {...item.nodeProps} />; );
}, },
label: item.label && (() => (typeof item.label === "string" ? item.label : item.label?.(args))), });
help: item.help && (() => (typeof item.help === "string" ? item.help : item.help?.(args))),
extra: item.extra && (() => (typeof item.extra === "string" ? item.extra : item.extra?.(args))), type FormItemFnArg<T = IFormItem> = {
}} item: T;
</BaseFormItem> items: T[];
); model: Record<string, any>;
}; };
type FormItemBase = { type FormItemBase = {
@ -105,7 +115,7 @@ type FormItemBase = {
* *
* @description FormItemlabel * @description FormItemlabel
*/ */
label?: string | ((args: { item: IFormItem; model: Record<string, any> }) => any); label?: string | ((args: FormItemFnArg) => any);
/** /**
* `FormItem` * `FormItem`
@ -136,45 +146,45 @@ type FormItemBase = {
*``` *```
* @see https://arco.design/vue/component/form#FieldRule * @see https://arco.design/vue/component/form#FieldRule
*/ */
rules?: FieldRuleType[]; rules?: FieldObjectRule<IFormItem>[];
/** /**
* *
* @description * @description
*/ */
visible?: (arg: { item: IFormItem; model: Record<string, any> }) => boolean; visible?: (arg: FormItemFnArg) => boolean;
/** /**
* *
* @description * @description
*/ */
disable?: (arg: { item: IFormItem; model: Record<string, any> }) => boolean; disable?: (arg: FormItemFnArg) => boolean;
/** /**
* *
* @description , * @description ,
*/ */
options?: SelectOptionData[] | ((arg: { item: IFormItem; model: Record<string, any> }) => Promise<any>); options?: SelectOptionData[] | ((arg: FormItemFnArg) => Promise<any>);
/** /**
* *
* @description * @description
*/ */
component?: (args: { item: IFormItem; model: Record<string, any>; field: string }) => any; component?: (args: FormItemFnArg) => any;
/** /**
* *
* @description FormItemhelp * @description FormItemhelp
* @see https://arco.design/vue/component/form#form-item%20Slots * @see https://arco.design/vue/component/form#form-item%20Slots
*/ */
help?: string | ((args: { item: IFormItem; model: Record<string, any> }) => any); help?: string | ((args: FormItemFnArg) => any);
/** /**
* *
* @description FormItemextra * @description FormItemextra
* @see https://arco.design/vue/component/form#form-item%20Slots * @see https://arco.design/vue/component/form#form-item%20Slots
*/ */
extra?: string | ((args: { item: IFormItem; model: Record<string, any> }) => any); extra?: string | ((args: FormItemFnArg) => any);
}; };
export type IFormItem = FormItemBase & NodeUnion; export type IFormItem = FormItemBase & NodeUnion;

View File

@ -224,7 +224,7 @@ export type NodeUnion = {
/** /**
* `input` * `input`
*/ */
type: key; type?: key;
/** /**
* `type` * `type`
*/ */

View File

@ -1,8 +1,10 @@
import { FieldRule } from "@arco-design/web-vue"; import { FieldRule } from "@arco-design/web-vue";
import { isString } from "lodash-es";
const defineRuleMap = <T extends Record<string, FieldRule>>(ruleMap: T) => ruleMap; /**
*
export const RuleMap = defineRuleMap({ */
export const FieldRuleMap = defineRuleMap({
required: { required: {
required: true, required: true,
message: "该项不能为空", message: "该项不能为空",
@ -44,3 +46,47 @@ export const RuleMap = defineRuleMap({
message: "至少包含大写字母、小写字母、数字和特殊字符", message: "至少包含大写字母、小写字母、数字和特殊字符",
}, },
}); });
/**
* ()
*/
export type FieldStringRule = keyof typeof FieldRuleMap;
/**
*
*/
export type FieldObjectRule<T> = FieldRule & {
disable?: (arg: { item: T; model: Record<string, any> }) => boolean;
};
/**
*
*/
export type Rule<T> = FieldStringRule | FieldObjectRule<T>;
/**
* (TS)
*/
function defineRuleMap<T extends Record<string, FieldRule>>(ruleMap: T) {
return ruleMap;
}
/**
*
* @param item
* @returns
*/
export const useFieldRules = <T extends { required?: boolean; rules?: Rule<any>[] }>(item: T) => {
const rules: FieldObjectRule<T>[] = [];
if (item.required) {
rules.push(FieldRuleMap.required);
}
for (const rule of item.rules ?? []) {
if (isString(rule)) {
rules.push(FieldRuleMap[rule]);
} else {
rules.push(rule);
}
}
return rules;
};

View File

@ -1,8 +1,8 @@
import { Form as BaseForm, FormInstance as BaseFormInstance, Message } from "@arco-design/web-vue"; import { Form as BaseForm, FormInstance as BaseFormInstance, Message } from "@arco-design/web-vue";
import { assign, cloneDeep, defaultsDeep } from "lodash-es"; import { assign, cloneDeep, defaultsDeep, merge } from "lodash-es";
import { PropType } from "vue"; import { PropType } from "vue";
import { FormItem, IFormItem } from "./form-item"; import { FormItem, IFormItem } from "./form-item";
import { NodeType, nodeMap } from "./form-node"; import { nodeMap } from "./form-node";
import { config } from "./form-config"; import { config } from "./form-config";
type SubmitFn = (arg: { model: Record<string, any>; items: IFormItem[] }) => Promise<any>; type SubmitFn = (arg: { model: Record<string, any>; items: IFormItem[] }) => Promise<any>;
@ -11,13 +11,13 @@ type SubmitFn = (arg: { model: Record<string, any>; items: IFormItem[] }) => Pro
* *
*/ */
export const Form = defineComponent({ export const Form = defineComponent({
name: "Form", name: "AppnifyForm",
props: { props: {
/** /**
* *
*/ */
model: { model: {
type: Object as PropType<Record<any, any>>, type: Object as PropType<Recordable>,
default: () => reactive({}), default: () => reactive({}),
}, },
/** /**
@ -45,11 +45,11 @@ export const Form = defineComponent({
const formRef = ref<InstanceType<typeof BaseForm>>(); const formRef = ref<InstanceType<typeof BaseForm>>();
const loading = ref(false); const loading = ref(false);
props.items.forEach((item: any) => { for (const item of props.items) {
const node = nodeMap[item.type as NodeType]; const node = nodeMap[item.type] as any;
defaultsDeep(item, { nodeProps: node?.nodeProps ?? {} }); defaultsDeep(item, { nodeProps: node?.nodeProps ?? {} });
(node as any)?.init?.({ item, model: props.model }); (node as any)?.init?.({ item, model: props.model });
}); }
const getItem = (field: string) => { const getItem = (field: string) => {
return props.items.find((item) => item.field === field); return props.items.find((item) => item.field === field);
@ -64,7 +64,7 @@ export const Form = defineComponent({
}; };
const resetModel = () => { const resetModel = () => {
assign(props.model, model); assign(props.model, merge({}, model));
}; };
const submitForm = async () => { const submitForm = async () => {
@ -84,7 +84,7 @@ export const Form = defineComponent({
} }
}; };
return { const injected = {
formRef, formRef,
loading, loading,
getItem, getItem,
@ -93,6 +93,10 @@ export const Form = defineComponent({
setModel, setModel,
getModel, getModel,
}; };
provide("form1", injected);
return injected;
}, },
render() { render() {
(this.items as any).instance = this; (this.items as any).instance = this;
@ -104,9 +108,9 @@ export const Form = defineComponent({
}; };
return ( return (
<BaseForm ref="formRef" layout="vertical" model={this.model} {...this.$attrs} {...this.formProps}> <BaseForm layout="vertical" {...this.$attrs} {...this.formProps} ref="formRef" model={this.model}>
{this.items.map((item) => ( {this.items.map((item) => (
<FormItem loading={this.loading} onSubmit={this.submitForm} item={item} {...props}></FormItem> <FormItem item={item} {...props}></FormItem>
))} ))}
</BaseForm> </BaseForm>
); );

View File

@ -0,0 +1,21 @@
import { FormInstance } from "@arco-design/web-vue";
import { FormItem, FormItemFnArg } from "./FormItem";
export type UseForm = {
/**
*
*/
model?: Recordable;
/**
*
*/
items?: FormItem[];
/**
*
*/
submit?: (arg: Omit<FormItemFnArg, "item">) => PromiseLike<any>;
/**
*
*/
formProps?: Partial<FormInstance["$props"]>;
};

View File

@ -0,0 +1,115 @@
import { FormItemInstance, SelectOptionData } from "@arco-design/web-vue";
import { Rule } from "../useRules";
import { NodeUnion } from "../../form-node";
/**
*
*/
export type FormItemFnArg<T = FormItem> = {
item: T;
items: T[];
model: Recordable;
};
/**
*
*/
type BaseFormItem = {
/**
* `FormItem`
* @description fieldlabelrequiredrulesdisabled
*/
itemProps?: Omit<FormItemInstance["$props"], "field" | "label" | "required" | "rules" | "disabled">;
/**
*
* @description
*/
visible?: (arg: FormItemFnArg) => boolean;
/**
*
* @description
*/
disable?: (arg: FormItemFnArg) => boolean;
/**
*
* @description ,
*/
options?: SelectOptionData[] | ((arg: FormItemFnArg) => PromiseLike<Recordable[]>);
};
/**
*
*/
type BaseFormItemSlots = {
/**
*
* @description
*/
render?: (args: FormItemFnArg) => any;
/**
*
* @description FormItemlabel
*/
label?: string | ((args: FormItemFnArg) => any);
/**
*
* @description FormItemhelp
* @see https://arco.design/vue/component/form#form-item%20Slots
*/
help?: string | ((args: FormItemFnArg) => any);
/**
*
* @description FormItemextra
* @see https://arco.design/vue/component/form#form-item%20Slots
*/
extra?: string | ((args: FormItemFnArg) => any);
};
/**
*
*/
type BaseFormItemRules = {
/**
*
* @description false
*/
required?: boolean;
/**
*
* @description ()
* @see https://arco.design/vue/component/form#FieldRule
*/
rules?: Rule<FormItem>[];
};
/**
*
*/
type BaseFormItemModel = {
/**
*
* @example
* ```typescript
* '[v1,v2]' => { v1: 1, v2: 2 }
* ```
*/
field: string;
/**
*
* @description model
*/
initial?: any;
};
/**
*
*/
export type FormItem = BaseFormItem & BaseFormItemModel & BaseFormItemRules & BaseFormItemSlots & NodeUnion;

View File

@ -0,0 +1,22 @@
import { useModel } from "./useModel";
import { useItems } from "./useItems";
import { UseOptions } from "./interface";
import { UseForm } from "./types/Form";
/**
*
*/
export const useForm = <T extends UseForm>(options: T) => {
const initModel = options.model ?? {};
const { items, updateItemOptions } = useItems(options.items ?? [], initModel, Boolean(options.submit));
const { model, resetModel, setModel, getModel } = useModel(initModel);
return {
model,
items,
resetModel,
setModel,
getModel,
updateItemOptions,
};
};

View File

@ -0,0 +1,52 @@
import { merge } from "lodash-es";
import { FormItem } from "./types/FormItem";
import { nodeMap } from "../form-node";
import { useRules } from "./useRules";
const ITEM: Partial<FormItem> = {
type: "input",
};
const SUBMIT_ITEM: FormItem = {
field: "id",
type: "submit",
itemProps: {
hideLabel: true,
},
};
export function useItems(list: FormItem[], model: Recordable, submit: boolean) {
const items = ref<FormItem[]>([]);
let hasSubmit = false;
for (const item of list) {
let target: Recordable = merge({}, nodeMap[item.type ?? "input"]);
if (item.type === "submit") {
target = merge(item, SUBMIT_ITEM);
hasSubmit = true;
}
target = merge(item, item);
target.rules = useRules(item);
model[item.field] = model[item.field] ?? item.initial;
items.value.push(target as any);
}
if (submit && !hasSubmit) {
items.value.push(merge({}, SUBMIT_ITEM));
}
const updateItemOptions = (field: string) => {
const item = items.value.find((i) => i.field === field);
if (item) {
(item as any)._updateOptions?.();
}
};
return {
items,
updateItemOptions,
};
}

View File

@ -0,0 +1,63 @@
import { cloneDeep } from "lodash-es";
function formatModel(model: Recordable) {
const data: Recordable = {};
for (const [key, val] of Object.entries(model)) {
// 数组类型
if (/^\[.+\]$/.test(key)) {
const subkeysStr = key.replaceAll(/\s/g, "").match(/^\[(.+)\]$/)?.[1];
if (!subkeysStr) {
data[key] = val;
continue;
}
const subkeys = subkeysStr.split(",");
subkeys.forEach((subkey, index) => {
if (/(.+)?:number$/.test(subkey)) {
subkey = subkey.replace(/:number$/, "");
data[subkey] = val?.[index] && Number(val[index]);
return;
}
if (/(.+)?:boolean$/.test(subkey)) {
subkey = subkey.replace(/:boolean$/, "");
data[subkey] = val?.[index] && Boolean(val[index]);
return;
}
data[subkey] = val?.[index];
});
continue;
}
// 默认类型
data[key] = val;
}
return data;
}
/**
*
* @param initial
* @returns
*/
export function useModel(initial: Recordable) {
const model = ref<Recordable>({});
const resetModel = () => {
model.value = cloneDeep(initial);
};
const setModel = (data: Recordable) => {
for (const key of Object.keys(model.value)) {
model.value[key] = data[key];
}
};
const getModel = () => {
return formatModel(model.value);
};
return {
model,
resetModel,
setModel,
getModel,
};
}

View File

@ -0,0 +1,92 @@
import { FieldRule } from "@arco-design/web-vue";
import { isString } from "lodash-es";
/**
*
*/
export const FieldRuleMap = defineRuleMap({
required: {
required: true,
message: "该项不能为空",
},
string: {
type: "string",
message: "请输入字符串",
},
number: {
type: "number",
message: "请输入数字",
},
email: {
type: "email",
message: "邮箱格式错误,示例: xx@abc.com",
},
url: {
type: "url",
message: "URL格式错误, 示例: www.abc.com",
},
ip: {
type: "ip",
message: "IP格式错误, 示例: 101.10.10.30",
},
phone: {
match: /^(?:(?:\+|00)86)?1\d{10}$/,
message: "手机格式错误, 示例(11位): 15912345678",
},
idcard: {
match: /^[1-9]\d{5}(?:18|19|20)\d{2}(?:0[1-9]|10|11|12)(?:0[1-9]|[1-2]\d|30|31)\d{3}[\dXx]$/,
message: "身份证格式错误, 长度为15或18位",
},
alphabet: {
match: /^[a-zA-Z]\w{4,15}$/,
message: "请输入英文字母, 长度为4~15位",
},
password: {
match: /^\S*(?=\S{6,})(?=\S*\d)(?=\S*[A-Z])(?=\S*[a-z])(?=\S*[!@#$%^&*? ])\S*$/,
message: "至少包含大写字母、小写字母、数字和特殊字符",
},
});
/**
* ()
*/
export type FieldStringRule = keyof typeof FieldRuleMap;
/**
*
*/
export type FieldObjectRule<T> = FieldRule & {
disable?: (arg: { item: T; model: Record<string, any> }) => boolean;
};
/**
*
*/
export type Rule<T> = FieldStringRule | FieldObjectRule<T>;
/**
* (TS)
*/
function defineRuleMap<T extends Record<string, FieldRule>>(ruleMap: T) {
return ruleMap;
}
/**
*
* @param item
* @returns
*/
export const useRules = <T extends { required?: boolean; rules?: Rule<any>[] }>(item: T) => {
const rules: FieldObjectRule<T>[] = [];
if (item.required) {
rules.push(FieldRuleMap.required);
}
for (const rule of item.rules ?? []) {
if (isString(rule)) {
rules.push(FieldRuleMap[rule]);
} else {
rules.push(rule);
}
}
return rules;
};

View File

@ -1,6 +1,7 @@
import { FormInstance } from "@arco-design/web-vue"; import { FormInstance } from "@arco-design/web-vue";
import { IFormItem } from "./form-item"; import { IFormItem } from "./form-item";
import { merge } from "lodash-es"; import { useModel } from "./hooks/useModel";
import { useItems } from "./hooks/useItems";
export type Options = { export type Options = {
/** /**
@ -26,34 +27,16 @@ export type Options = {
* @see src/components/form/use-form.tsx * @see src/components/form/use-form.tsx
*/ */
export const useForm = (options: Options) => { export const useForm = (options: Options) => {
const { model: _model = {} } = options; const initModel = options.model ?? {};
const model: Record<string, any> = { id: undefined, ..._model }; const { items, updateItemOptions } = useItems(options.items, initModel, Boolean(options.submit));
const items: IFormItem[] = []; const { model, resetModel, setModel, getModel } = useModel(initModel);
for (const item of options.items) { return {
if (!item.nodeProps) { model,
item.nodeProps = {} as any; items,
} resetModel,
model[item.field] = model[item.field] ?? item.initial; setModel,
items.push(item); getModel,
} updateItemOptions,
};
if (options.submit) {
const submit = items.find((item) => item.type === "submit") || {};
items.push(
merge(
{},
{
field: "id",
type: "submit",
itemProps: {
hideLabel: true,
},
},
submit
) as any
);
}
return reactive({ ...options, model, items }) as any;
}; };

View File

@ -32,3 +32,21 @@ export function setModel(model: any, data: Record<string, any>) {
} }
} }
} }
/**
*
* @param value
* @param arg
* @returns
*/
export function strOrFnRender(value?: string | Function, arg?: any) {
if (typeof value === "string") {
return () => value;
}
if (typeof value === "function") {
return () => value(arg);
}
return null;
}
export const falsy = () => false;

View File

@ -1,11 +1,16 @@
import { TableColumnData as BaseColumn, TableData as BaseData, Table as BaseTable } from "@arco-design/web-vue"; import {
import { merge } from "lodash-es"; TableColumnData as BaseColumn,
TableData as BaseData,
Table as BaseTable,
PaginationProps,
} from "@arco-design/web-vue";
import { cloneDeep, isBoolean, isObject, merge } from "lodash-es";
import { PropType, computed, defineComponent, reactive, ref } from "vue"; import { PropType, computed, defineComponent, reactive, ref } from "vue";
import AniEmpty from "../empty/AniEmpty.vue"; import AniEmpty from "../empty/AniEmpty.vue";
import { Form, FormInstance, FormModal, FormModalInstance, FormModalProps, FormProps } from "../form"; import { Form, FormInstance, FormModal, FormModalInstance, FormModalProps, FormProps } from "../form";
import { config } from "./table.config"; import { config } from "./table.config";
type DataFn = (search: Record<string, any>, paging: { page: number; size: number }) => Promise<any>; type DataFn = (search: Record<string, any>, paging: { page: number; size: number }) => PromiseLike<any>;
/** /**
* *
@ -32,8 +37,7 @@ export const Table = defineComponent({
* *
*/ */
pagination: { pagination: {
type: Object as PropType<any>, type: [Boolean, Object] as PropType<boolean | PaginationProps>,
default: () => reactive(config.pagination),
}, },
/** /**
* *
@ -73,6 +77,7 @@ export const Table = defineComponent({
const createRef = ref<FormModalInstance>(); const createRef = ref<FormModalInstance>();
const modifyRef = ref<FormModalInstance>(); const modifyRef = ref<FormModalInstance>();
const renderData = ref<BaseData[]>([]); const renderData = ref<BaseData[]>([]);
const paging = ref<PaginationProps>(merge({}, isObject(props.pagination) ? props.pagination : config.pagination));
const inlined = computed(() => (props.search?.items?.length ?? 0) <= config.searchInlineCount); const inlined = computed(() => (props.search?.items?.length ?? 0) <= config.searchInlineCount);
const reloadData = () => loadData({ current: 1, pageSize: 10 }); const reloadData = () => loadData({ current: 1, pageSize: 10 });
const openModifyModal = (data: any) => modifyRef.value?.open(data); const openModifyModal = (data: any) => modifyRef.value?.open(data);
@ -81,9 +86,8 @@ export const Table = defineComponent({
* *
* @param pagination * @param pagination
*/ */
const loadData = async (pagination: Partial<any> = {}) => { const loadData = async (pagination: Partial<PaginationProps> = {}) => {
const merged = { ...props.pagination, ...pagination }; const { current: page = 1, pageSize: size = 10 } = { ...paging.value, ...pagination };
const paging = { page: merged.current, size: merged.pageSize };
const model = searchRef.value?.getModel() ?? {}; const model = searchRef.value?.getModel() ?? {};
// 本地加载 // 本地加载
@ -98,21 +102,21 @@ export const Table = defineComponent({
}); });
}); });
renderData.value = data; renderData.value = data;
props.pagination.total = renderData.value.length; paging.value.total = renderData.value.length;
props.pagination.current = 1; paging.value.current = 1;
} }
// 远程加载 // 远程加载
if (typeof props.data === "function") { if (typeof props.data === "function") {
try { try {
loading.value = true; loading.value = true;
const resData = await props.data(model, paging); const resData = await props.data(model, { page, size });
const { data = [], total = 0 } = resData?.data || {}; const { data = [], total = 0 } = resData?.data || {};
renderData.value = data; renderData.value = data;
props.pagination.total = total; paging.value.total = total;
props.pagination.current = paging.page; paging.value.current = page;
} catch (e) { } catch (e) {
// todo console.log(e);
} finally { } finally {
loading.value = false; loading.value = false;
} }
@ -122,8 +126,8 @@ export const Table = defineComponent({
watchEffect(() => { watchEffect(() => {
if (Array.isArray(props.data)) { if (Array.isArray(props.data)) {
renderData.value = props.data; renderData.value = props.data;
props.pagination.total = props.data.length; paging.value.total = props.data.length;
props.pagination.current = 1; paging.value.current = 1;
} }
}); });
@ -143,6 +147,7 @@ export const Table = defineComponent({
createRef, createRef,
modifyRef, modifyRef,
renderData, renderData,
paging,
loadData, loadData,
reloadData, reloadData,
openModifyModal, openModifyModal,
@ -177,7 +182,10 @@ export const Table = defineComponent({
)} )}
{this.$slots.action?.()} {this.$slots.action?.()}
</div> </div>
<div>{this.inlined && <Form ref="searchRef" {...this.search}></Form>}</div> <div>
{this.inlined && <Form ref="searchRef" {...this.search}></Form>}
{this.$slots.tool?.(this.renderData)}
</div>
</div> </div>
<BaseTable <BaseTable
@ -187,7 +195,7 @@ export const Table = defineComponent({
{...this.$attrs} {...this.$attrs}
{...this.tableProps} {...this.tableProps}
loading={this.loading} loading={this.loading}
pagination={this.pagination} pagination={this.pagination && this.paging}
data={this.renderData} data={this.renderData}
columns={this.columns} columns={this.columns}
onPageChange={(current: number) => this.loadData({ current })} onPageChange={(current: number) => this.loadData({ current })}

View File

@ -7,7 +7,9 @@ declare module "*.vue" {
export default component; export default component;
} }
declare module 'numeral' { declare module "numeral" {
const numeral: any const numeral: any;
export default numeral; export default numeral;
} }
type Recordable = Record<string, any>;