mirror of
https://gitee.com/dromara/mayfly-go
synced 2026-03-11 12:35:36 +08:00
refactor: PageTable优化
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
<component
|
||||
:is="item?.render ?? `el-${item.type}`"
|
||||
v-bind="{ ...handleSearchProps, ...placeholder, clearable: true }"
|
||||
v-on="{ ...handleEvents }"
|
||||
v-model.trim="itemValue"
|
||||
:data="item.type === 'tree-select' ? item.options : []"
|
||||
:options="['cascader', 'select-v2'].includes(item.type!) ? item.options : []"
|
||||
@@ -48,19 +49,6 @@ const fieldNames = computed(() => {
|
||||
};
|
||||
});
|
||||
|
||||
// 接收 enumMap (el 为 select-v2 需单独处理 enumData)
|
||||
// const enumMap = inject('enumMap', ref(new Map()));
|
||||
// const columnEnum = computed(() => {
|
||||
// let enumData = enumMap.value.get(props.item.prop);
|
||||
// if (!enumData) return [];
|
||||
// if (props.item?.type === 'select-v2' && props.item.fieldNames) {
|
||||
// enumData = enumData.map((item: { [key: string]: any }) => {
|
||||
// return { ...item, label: item[fieldNames.value.label], value: item[fieldNames.value.value] };
|
||||
// });
|
||||
// }
|
||||
// return enumData;
|
||||
// });
|
||||
|
||||
// 处理透传的 searchProps (type 为 tree-select、cascader 的时候需要给下默认 label && value && children)
|
||||
const handleSearchProps = computed(() => {
|
||||
const label = fieldNames.value.label;
|
||||
@@ -77,6 +65,12 @@ const handleSearchProps = computed(() => {
|
||||
return searchProps;
|
||||
});
|
||||
|
||||
// 处理透传的 事件
|
||||
const handleEvents = computed(() => {
|
||||
let itemEvents = props.item?.props ?? {};
|
||||
return itemEvents;
|
||||
});
|
||||
|
||||
// 处理默认 placeholder
|
||||
const placeholder = computed(() => {
|
||||
const search = props.item;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { VNode } from 'vue';
|
||||
import Api from '@/common/Api';
|
||||
import { VNode, ref, toValue } from 'vue';
|
||||
|
||||
export type FieldNamesProps = {
|
||||
label: string;
|
||||
@@ -19,6 +20,78 @@ export type SearchItemType =
|
||||
| 'switch'
|
||||
| 'slider';
|
||||
|
||||
/**
|
||||
* 表单组件可选项的api信息
|
||||
*/
|
||||
export class OptionsApi {
|
||||
/**
|
||||
* 请求获取options的api
|
||||
*/
|
||||
api: Api;
|
||||
|
||||
/**
|
||||
* 请求参数
|
||||
*/
|
||||
params: any;
|
||||
|
||||
/**
|
||||
* 是否立即执行,否则在组件focus事件中获取
|
||||
*/
|
||||
immediate: boolean = false;
|
||||
|
||||
/**
|
||||
* 是否只获取一次,即若以获取则不继续调用该api
|
||||
*/
|
||||
once: boolean = true;
|
||||
|
||||
/**
|
||||
* 转换函数,主要用于将响应的api结果转换为满足组件options的结构
|
||||
*/
|
||||
convertFn: (apiResp: any) => any;
|
||||
|
||||
withConvertFn(fn: (apiResp: any) => any) {
|
||||
this.convertFn = fn;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 立即获取该可选值
|
||||
* @returns
|
||||
*/
|
||||
withImmediate() {
|
||||
this.immediate = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设为非一次性api,即每次组件focus获取的时候都允许重新获取options
|
||||
* @returns this
|
||||
*/
|
||||
withNoOnce() {
|
||||
this.once = false;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 调用api获取组件可选项
|
||||
* @returns 组件可选项信息
|
||||
*/
|
||||
async getOptions() {
|
||||
let res = await this.api.request(toValue(this.params));
|
||||
if (this.convertFn) {
|
||||
res = this.convertFn(res);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
static new(api: Api, params: any): OptionsApi {
|
||||
const oa = new OptionsApi();
|
||||
oa.api = api;
|
||||
oa.params = params;
|
||||
return oa;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 搜索项
|
||||
*/
|
||||
@@ -43,22 +116,50 @@ export class SearchItem {
|
||||
*/
|
||||
options: any;
|
||||
|
||||
/**
|
||||
* 获取可选项的api信息
|
||||
*/
|
||||
optionsApi: OptionsApi;
|
||||
|
||||
/**
|
||||
* 插槽名
|
||||
*/
|
||||
slot: string;
|
||||
|
||||
props?: any; // 搜索项参数,根据 element plus 官方文档来传递,该属性所有值会透传到组件
|
||||
/**
|
||||
* 搜索项参数,根据 element plus 官方文档来传递,该属性所有值会透传到组件
|
||||
*/
|
||||
props?: any;
|
||||
|
||||
tooltip?: string; // 搜索提示
|
||||
/**
|
||||
* 搜索项事件,根据 element plus 官方文档来传递,该属性所有值会透传到组件
|
||||
*/
|
||||
events?: any;
|
||||
|
||||
span?: number; // 搜索项所占用的列数,默认为 1 列
|
||||
/**
|
||||
* 搜索提示
|
||||
*/
|
||||
tooltip?: string;
|
||||
|
||||
offset?: number; // 搜索字段左侧偏移列数
|
||||
/**
|
||||
* 搜索项所占用的列数,默认为 1 列
|
||||
*/
|
||||
span?: number;
|
||||
|
||||
fieldNames: FieldNamesProps; // 指定 label && value && children 的 key 值,用于select等类型组件
|
||||
/**
|
||||
* 搜索字段左侧偏移列数
|
||||
*/
|
||||
offset?: number;
|
||||
|
||||
render?: (scope: any) => VNode; // 自定义搜索内容渲染(tsx语法)
|
||||
/**
|
||||
* 指定 label && value && children 的 key 值,用于select等类型组件
|
||||
*/
|
||||
fieldNames: FieldNamesProps;
|
||||
|
||||
/**
|
||||
* 自定义搜索内容渲染(tsx语法)
|
||||
*/
|
||||
render?: (scope: any) => VNode;
|
||||
|
||||
constructor(prop: string, label: string) {
|
||||
this.prop = prop;
|
||||
@@ -69,7 +170,7 @@ export class SearchItem {
|
||||
return new SearchItem(prop, label);
|
||||
}
|
||||
|
||||
static text(prop: string, label: string): SearchItem {
|
||||
static input(prop: string, label: string): SearchItem {
|
||||
const tq = new SearchItem(prop, label);
|
||||
tq.type = 'input';
|
||||
return tq;
|
||||
@@ -78,10 +179,11 @@ export class SearchItem {
|
||||
static select(prop: string, label: string): SearchItem {
|
||||
const tq = new SearchItem(prop, label);
|
||||
tq.type = 'select';
|
||||
tq.withOneProps('filterable', true);
|
||||
return tq;
|
||||
}
|
||||
|
||||
static date(prop: string, label: string): SearchItem {
|
||||
static datePicker(prop: string, label: string): SearchItem {
|
||||
const tq = new SearchItem(prop, label);
|
||||
tq.type = 'date-picker';
|
||||
return tq;
|
||||
@@ -93,8 +195,40 @@ export class SearchItem {
|
||||
return tq;
|
||||
}
|
||||
|
||||
withSpan(span: number): SearchItem {
|
||||
this.span = span;
|
||||
/**
|
||||
* 为组件设置一个props属性
|
||||
* @param propsKey 属性key
|
||||
* @param propsValue 属性value
|
||||
* @returns
|
||||
*/
|
||||
withOneProps(propsKey: string, propsValue: any): SearchItem {
|
||||
if (!this.props) {
|
||||
this.props = {};
|
||||
}
|
||||
this.props[propsKey] = propsValue;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 为组件传递组件自身的props属性 (根据 element plus 官方文档来传递,该属性所有值会透传到组件)
|
||||
* @returns this
|
||||
*/
|
||||
withProps(props: any = {}): SearchItem {
|
||||
this.props = props;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 为组件传递组件自身事件函数
|
||||
* @param event 事件名称
|
||||
* @param fn 事件处理函数
|
||||
* @returns
|
||||
*/
|
||||
bindEvent(event: string, eventFn: any): SearchItem {
|
||||
if (!this.events) {
|
||||
this.events = {};
|
||||
}
|
||||
this.props[event] = eventFn;
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -108,7 +242,38 @@ export class SearchItem {
|
||||
return this;
|
||||
}
|
||||
|
||||
setOptions(options: any): SearchItem {
|
||||
/**
|
||||
* 设置获取组件options可选项值的api配置
|
||||
* @param optionsApi 可选项api配置
|
||||
* @returns this
|
||||
*/
|
||||
withOptionsApi(optionsApi: OptionsApi): SearchItem {
|
||||
this.optionsApi = optionsApi;
|
||||
// 使用api获取组件可选项需要将options转为响应式,否则组件无法响应式获取组件可选项
|
||||
this.options = ref(null);
|
||||
|
||||
// 立即执行,则直接调用api获取并赋值options
|
||||
if (this.optionsApi.immediate) {
|
||||
this.optionsApi.getOptions().then((res) => {
|
||||
this.options.value = res;
|
||||
});
|
||||
} else {
|
||||
// 注册focus事件,在触发focus时赋值options
|
||||
this.bindEvent('focus', async () => {
|
||||
if (!toValue(this.options) || !optionsApi.once) {
|
||||
this.options.value = await this.optionsApi.getOptions();
|
||||
}
|
||||
});
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
withSpan(span: number): SearchItem {
|
||||
this.span = span;
|
||||
return this;
|
||||
}
|
||||
|
||||
withOptions(options: any): SearchItem {
|
||||
this.options = options;
|
||||
return this;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user