1
0
mirror of synced 2026-02-04 18:47:57 +08:00

refactor(form): 优化创建初始值等一些工具函数

This commit is contained in:
roymondchen
2026-01-08 17:11:05 +08:00
parent 8956035e41
commit e6d1624a6c
2 changed files with 169 additions and 14 deletions

View File

@@ -46,8 +46,8 @@ interface DefaultItem {
names?: string[];
}
const isTableSelect = (type?: string | TypeFunction) =>
typeof type === 'string' && ['table-select', 'tableSelect'].includes(type);
const TABLE_SELECT_TYPES = new Set(['table-select', 'tableSelect']);
const isTableSelect = (type?: string | TypeFunction) => typeof type === 'string' && TABLE_SELECT_TYPES.has(type);
const asyncLoadConfig = (value: FormValue, initValue: FormValue, { asyncLoad, name, type }: HtmlField) => {
// 富文本配置了异步加载
@@ -57,9 +57,15 @@ const asyncLoadConfig = (value: FormValue, initValue: FormValue, { asyncLoad, na
}
};
const isMultipleValue = (type?: string | TypeFunction) =>
typeof type === 'string' &&
['checkbox-group', 'checkboxGroup', 'table', 'cascader', 'group-list', 'groupList'].includes(type);
const MULTIPLE_VALUE_TYPES = new Set([
'checkbox-group',
'checkboxGroup',
'table',
'cascader',
'group-list',
'groupList',
]);
const isMultipleValue = (type?: string | TypeFunction) => typeof type === 'string' && MULTIPLE_VALUE_TYPES.has(type);
const initItemsValue = (
mForm: FormState | undefined,
@@ -309,7 +315,8 @@ export const datetimeFormatter = (
let time: string | number;
if (['x', 'timestamp'].includes(format)) {
time = dayjs(Number.isNaN(Number(v)) ? v : Number(v)).valueOf();
} else if ((typeof v === 'string' && v.includes('Z')) || v.constructor === Date) {
} else if ((typeof v === 'string' && v.includes('Z')) || v instanceof Date) {
// dayjs.extend 内部有防重复机制 (plugin.$i),无需额外判断
dayjs.extend(utc);
// UTC字符串时间或Date对象格式化为北京时间
time = dayjs(v).utcOffset(8).format(format);
@@ -325,10 +332,10 @@ export const datetimeFormatter = (
return defaultValue;
};
export const getDataByPage = (data: any[] = [], pagecontext: number, pagesize: number) =>
data.filter(
(item: any, index: number) => index >= pagecontext * pagesize && index + 1 <= (pagecontext + 1) * pagesize,
);
export const getDataByPage = (data: any[] = [], pagecontext: number, pagesize: number) => {
const start = pagecontext * pagesize;
return data.slice(start, start + pagesize);
};
export const sortArray = (data: any[], newIndex: number, oldIndex: number, sortKey?: string) => {
if (newIndex === oldIndex) {
@@ -339,7 +346,9 @@ export const sortArray = (data: any[], newIndex: number, oldIndex: number, sortK
return data;
}
const newData = data.toSpliced(newIndex, 0, ...data.splice(oldIndex, 1));
// 先取出要移动的元素,再使用 toSpliced 避免修改原数组
const item = data[oldIndex];
const newData = data.toSpliced(oldIndex, 1).toSpliced(newIndex, 0, item);
if (sortKey) {
for (let i = newData.length - 1, v = 0; i >= 0; i--, v++) {
@@ -352,8 +361,8 @@ export const sortArray = (data: any[], newIndex: number, oldIndex: number, sortK
export const sortChange = (data: any[], { prop, order }: SortProp) => {
if (order === 'ascending') {
data = data.sort((a: any, b: any) => a[prop] - b[prop]);
data.sort((a: any, b: any) => a[prop] - b[prop]);
} else if (order === 'descending') {
data = data.sort((a: any, b: any) => b[prop] - a[prop]);
data.sort((a: any, b: any) => b[prop] - a[prop]);
}
};

View File

@@ -18,7 +18,17 @@
import { describe, expect, test } from 'vitest';
import type { FormState } from '@form/index';
import { datetimeFormatter, display, filterFunction, getRules, initValue, sortArray } from '@form/utils/form';
import {
createValues,
datetimeFormatter,
display,
filterFunction,
getDataByPage,
getRules,
initValue,
sortArray,
sortChange,
} from '@form/utils/form';
// form state mock 数据
const mForm: FormState = {
@@ -70,6 +80,10 @@ describe('display', () => {
expect(display(mForm, () => false, {})).toBe(false);
expect(display(mForm, () => 1, {})).toBe(1);
});
test('config 为 expand', () => {
expect(display(mForm, 'expand', {})).toBe('expand');
});
});
describe('getRules', () => {
@@ -419,4 +433,136 @@ describe('sortArray', () => {
expect(sortArray(data, 5, 1)).toEqual(data);
expect(sortArray(data, 1, 5)).toEqual(data);
});
test('不修改原数组', () => {
const data = [1, 2, 3, 4, 5];
const original = [...data];
sortArray(data, 0, 3);
expect(data).toEqual(original);
});
test('返回的新数组与原数组不是同一引用', () => {
const data = [1, 2, 3, 4, 5];
const result = sortArray(data, 0, 3);
expect(result).not.toBe(data);
});
});
describe('getDataByPage', () => {
test('获取第一页数据', () => {
const data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
expect(getDataByPage(data, 0, 3)).toEqual([1, 2, 3]);
});
test('获取中间页数据', () => {
const data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
expect(getDataByPage(data, 1, 3)).toEqual([4, 5, 6]);
});
test('获取最后一页数据(不足一页)', () => {
const data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
expect(getDataByPage(data, 3, 3)).toEqual([10]);
});
test('页码超出范围返回空数组', () => {
const data = [1, 2, 3, 4, 5];
expect(getDataByPage(data, 10, 3)).toEqual([]);
});
test('空数组返回空数组', () => {
expect(getDataByPage([], 0, 10)).toEqual([]);
});
test('不修改原数组', () => {
const data = [1, 2, 3, 4, 5];
const original = [...data];
getDataByPage(data, 0, 2);
expect(data).toEqual(original);
});
test('默认空数组参数', () => {
expect(getDataByPage(undefined as any, 0, 10)).toEqual([]);
});
});
describe('sortChange', () => {
test('升序排序', () => {
const data = [{ value: 3 }, { value: 1 }, { value: 2 }];
sortChange(data, { prop: 'value', order: 'ascending' });
expect(data).toEqual([{ value: 1 }, { value: 2 }, { value: 3 }]);
});
test('降序排序', () => {
const data = [{ value: 1 }, { value: 3 }, { value: 2 }];
sortChange(data, { prop: 'value', order: 'descending' });
expect(data).toEqual([{ value: 3 }, { value: 2 }, { value: 1 }]);
});
test('无效的order不进行排序', () => {
const data = [{ value: 3 }, { value: 1 }, { value: 2 }];
const original = [{ value: 3 }, { value: 1 }, { value: 2 }];
sortChange(data, { prop: 'value', order: '' as any });
expect(data).toEqual(original);
});
test('空数组不报错', () => {
const data: any[] = [];
expect(() => sortChange(data, { prop: 'value', order: 'ascending' })).not.toThrow();
});
test('原地修改数组', () => {
const data = [{ value: 2 }, { value: 1 }];
sortChange(data, { prop: 'value', order: 'ascending' });
expect(data[0].value).toBe(1);
expect(data[1].value).toBe(2);
});
});
describe('createValues', () => {
test('config为空数组返回空对象', () => {
expect(createValues(mForm, [], {})).toEqual({});
});
test('config不是数组返回传入的value', () => {
const value = { a: 1 };
expect(createValues(mForm, undefined as any, {}, value)).toEqual(value);
});
test('处理简单的text配置', () => {
const config = [{ type: 'text', name: 'field1' }];
const initValues = { field1: 'hello' };
const result = createValues(mForm, config, initValues, {});
expect(result.field1).toBe('hello');
});
test('处理number类型转换', () => {
const config = [{ type: 'number', name: 'num' }];
const initValues = { num: '123' };
const result = createValues(mForm, config, initValues, {});
expect(result.num).toBe(123);
});
});