gi-component 0.0.5 → 0.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "gi-component",
3
3
  "type": "module",
4
- "version": "0.0.5",
4
+ "version": "0.0.7",
5
5
  "description": "Vue3中基于Element Plus二次封装基础组件库",
6
6
  "author": "lin",
7
7
  "license": "MIT",
@@ -10,6 +10,7 @@
10
10
  <template v-if="column.slotName">
11
11
  <slot :name="column.slotName" v-bind="scope"></slot>
12
12
  </template>
13
+ <template v-else-if="!column.type">{{ scope.row[column.prop] }}</template>
13
14
  <component :is="COMP_MAP[column.type] || column.type" v-else v-bind="getComponentBindProps(column)"
14
15
  v-model="scope.row[column.prop]" class="w-full" :disabled="isDisabled(scope)">
15
16
  </component>
@@ -38,7 +39,7 @@ const props = withDefaults(defineProps<EditTableProps>(), {
38
39
  const attrs = useAttrs();
39
40
  const { b } = useBemClass();
40
41
 
41
- const COMP_MAP: Record<Exclude<EditTableColumnItemType, 'slot'>, any> = {
42
+ const COMP_MAP: Record<EditTableColumnItemType, any> = {
42
43
  input: El.ElInput,
43
44
  textarea: El.ElInput,
44
45
  'input-number': El.ElInputNumber,
@@ -61,7 +62,8 @@ const COMP_MAP: Record<Exclude<EditTableColumnItemType, 'slot'>, any> = {
61
62
  transfer: El.ElTransfer,
62
63
  autocomplete: El.ElAutocomplete,
63
64
  upload: El.ElUpload,
64
- 'input-search': InputSearch
65
+ 'input-search': InputSearch,
66
+ slot: undefined,
65
67
  };
66
68
 
67
69
  const formRef = ref<FormInstance | null>();
@@ -137,11 +139,10 @@ function getComponentBindProps(item: EditTableColumnItem) {
137
139
  const defaultProps: any = STATIC_PROPS.get(item.type || '') || {};
138
140
  defaultProps.placeholder = getPlaceholder(item);
139
141
  if (item.type === 'date-picker') {
140
- defaultProps.valueFormat =
141
- item?.componentProps?.type === 'datetime' ? 'YYYY-MM-DD HH:mm:ss' : 'YYYY-MM-DD';
142
+ defaultProps.valueFormat = item?.componentProps?.type === 'datetime' ? 'YYYY-MM-DD HH:mm:ss' : 'YYYY-MM-DD';
142
143
  }
143
144
  // 合并默认配置和自定义配置
144
- return { ...defaultProps, ...item.componentProps };
145
+ return { ...defaultProps, ...(item?.componentProps || {}) };
145
146
  }
146
147
 
147
148
  /** 表单项校验规则 */
@@ -1,5 +1,6 @@
1
1
  import type * as El from 'element-plus';
2
2
  import type { InputSearchInstance } from '../../input-search'
3
+ import type { MergeMultiple } from '../../../types/tool'
3
4
 
4
5
  export type EditTableColumnItemType =
5
6
  | 'input'
@@ -34,34 +35,34 @@ export interface EditTableColumnItem {
34
35
  width?: number | string;
35
36
  required?: boolean;
36
37
  rules?: El.FormItemRule[]; // 表单校验规则
37
- componentProps?: ColumnItemProps;
38
+ componentProps?: EditTableColumnItemProps;
38
39
  columnProps?: El.TableColumnInstance['$props'];
39
40
  formItemProps?: El.FormItemProps;
40
41
  slotName?: string;
41
42
  }
42
43
 
43
- export type ColumnItemProps = El.InputProps &
44
- El.InputNumberProps &
45
- El.InputTagProps &
46
- El.SelectProps &
47
- El.SelectV2Props &
48
- El.TreeInstance['$props'] &
49
- El.CascaderProps &
50
- El.SliderProps &
51
- El.SwitchProps &
52
- El.RateProps &
53
- El.CheckboxGroupProps &
54
- El.CheckboxProps &
55
- El.RadioGroupProps &
56
- El.RadioProps &
57
- El.DatePickerProps &
58
- El.TimePickerDefaultProps &
59
- El.TimeSelectProps &
60
- El.ColorPickerProps &
61
- El.TransferProps &
62
- El.AutocompleteProps &
63
- El.UploadProps &
64
- InputSearchInstance['$props']
44
+ export type EditTableColumnItemProps = MergeMultiple<[El.InputProps,
45
+ El.InputNumberProps,
46
+ El.InputTagProps,
47
+ El.SelectProps,
48
+ El.SelectV2Props,
49
+ El.TreeInstance['$props'],
50
+ El.CascaderProps,
51
+ El.SliderProps,
52
+ El.SwitchProps,
53
+ El.RateProps,
54
+ El.CheckboxGroupProps,
55
+ El.CheckboxProps,
56
+ El.RadioGroupProps,
57
+ El.RadioProps,
58
+ El.DatePickerProps,
59
+ El.TimePickerDefaultProps,
60
+ El.TimeSelectProps,
61
+ El.ColorPickerProps,
62
+ El.TransferProps,
63
+ El.AutocompleteProps,
64
+ El.UploadProps,
65
+ InputSearchInstance['$props']]>
65
66
 
66
67
  export interface EditTableProps {
67
68
  rowKey?: string;
@@ -1,49 +1,22 @@
1
1
  <template>
2
- <el-form
3
- ref="formRef"
4
- :class="getClass"
5
- v-bind="formProps"
6
- :model="props.modelValue"
7
- >
8
- <Grid
9
- class="w-full"
10
- :col-gap="12"
11
- v-bind="props.gridProps"
12
- :collapsed="collapsed"
13
- >
2
+ <el-form ref="formRef" :class="getClass" v-bind="formProps" :model="props.modelValue">
3
+ <Grid class="w-full" :col-gap="12" v-bind="props.gridProps" :collapsed="collapsed">
14
4
  <template v-for="(item, index) in props.columns">
15
- <GridItem
16
- v-if="item.type === 'title'"
17
- :key="`title${index}`"
18
- :span="100"
19
- >
5
+ <GridItem v-if="item.type === 'title'" :key="`title${index}`" :span="100">
20
6
  <el-form-item label-width="0">
21
- <GiCard
22
- :title="typeof item.label === 'string' ? item.label : ''"
23
- :header-style="{ padding: 0 }"
24
- :body-style="{ display: 'none' }"
25
- ></GiCard>
7
+ <GiCard :title="typeof item.label === 'string' ? item.label : ''" :header-style="{ padding: 0 }"
8
+ :body-style="{ display: 'none' }"></GiCard>
26
9
  </el-form-item>
27
10
  </GridItem>
28
11
 
29
12
  <template v-else>
30
- <GridItem
31
- v-if="!isHide(item)"
32
- :key="item.field + index"
33
- v-bind="item.gridItemProps || props.gridItemProps"
34
- :span="
35
- item.span ||
13
+ <GridItem v-if="!isHide(item)" :key="item.field + index" v-bind="item.gridItemProps || props.gridItemProps"
14
+ :span="item.span ||
36
15
  item.gridItemProps?.span ||
37
16
  props?.gridItemProps?.span
38
- "
39
- >
40
- <el-form-item
41
- :key="item.field + index"
42
- :prop="item.field"
43
- :label="item.label"
44
- :rules="getFormItemRules(item)"
45
- v-bind="item.formItemProps"
46
- >
17
+ ">
18
+ <el-form-item :key="item.field + index" :prop="item.field" :label="item.label"
19
+ :rules="getFormItemRules(item)" v-bind="item.formItemProps">
47
20
  <template v-if="item?.labelRender" #label>
48
21
  <component :is="item.labelRender"></component>
49
22
  </template>
@@ -53,21 +26,10 @@
53
26
  <template v-else>
54
27
  <div :class="b('form-item__content')">
55
28
  <div :class="b('form-item__component')">
56
- <component
57
- :is="CompMap[item.type] || item.type"
58
- :disabled="isDisabled(item)"
59
- class="w-full"
60
- v-bind="getComponentBindProps(item)"
61
- :model-value="
62
- props.modelValue[item.fieldName || item.field]
63
- "
64
- @update:model-value="updateModelValue($event, item)"
65
- >
66
- <template
67
- v-for="(slotValue, slotKey) in item?.slots || {}"
68
- :key="slotKey"
69
- #[slotKey]="scope"
70
- >
29
+ <component :is="CompMap[item.type] || item.type" :disabled="isDisabled(item)" class="w-full"
30
+ v-bind="getComponentBindProps(item)" :model-value="props.modelValue[item.fieldName || item.field]
31
+ " @update:model-value="updateModelValue($event, item)">
32
+ <template v-for="(slotValue, slotKey) in item?.slots || {}" :key="slotKey" #[slotKey]="scope">
71
33
  <template v-if="typeof slotValue === 'string'">
72
34
  {{ slotValue }}
73
35
  </template>
@@ -76,12 +38,7 @@
76
38
  </template>
77
39
  </template>
78
40
  </component>
79
- <el-text
80
- v-if="item.tip"
81
- :class="b('form-item__tip')"
82
- type="info"
83
- size="small"
84
- >
41
+ <el-text v-if="item.tip" :class="b('form-item__tip')" type="info" size="small">
85
42
  {{ item.tip }}
86
43
  </el-text>
87
44
  </div>
@@ -90,7 +47,7 @@
90
47
  <template v-if="typeof item.extra === 'string'">
91
48
  <el-text type="info" size="small">{{
92
49
  item.extra
93
- }}</el-text>
50
+ }}</el-text>
94
51
  </template>
95
52
  <template v-else-if="item.extra">
96
53
  <component :is="item.extra"></component>
@@ -103,25 +60,14 @@
103
60
  </template>
104
61
  </template>
105
62
 
106
- <GridItem
107
- v-if="props.search"
108
- :suffix="props.search"
109
- :span="props?.gridItemProps?.span"
110
- >
63
+ <GridItem v-if="props.search" :suffix="props.search" :span="props?.gridItemProps?.span">
111
64
  <el-space :class="b('form__search-btns')">
112
65
  <el-button type="primary" @click="emit('search')">
113
66
  {{ searchText }}
114
67
  </el-button>
115
68
  <el-button @click="emit('reset')"> 重置 </el-button>
116
- <el-button
117
- v-if="!props.hideFoldBtn"
118
- class="form__fold-btn"
119
- type="primary"
120
- :icon="collapsed ? ArrowDown : ArrowUp"
121
- text
122
- size="small"
123
- @click="collapsed = !collapsed"
124
- >
69
+ <el-button v-if="!props.hideFoldBtn" class="form__fold-btn" type="primary"
70
+ :icon="collapsed ? ArrowDown : ArrowUp" text size="small" @click="collapsed = !collapsed">
125
71
  {{ collapsed ? '展开' : '收起' }}
126
72
  </el-button>
127
73
  </el-space>
@@ -251,15 +197,14 @@ function getComponentBindProps(item: FormColumnItem) {
251
197
  const defaultProps: any = STATIC_PROPS.get(item.type) || {};
252
198
  defaultProps.placeholder = getPlaceholder(item);
253
199
  if (item.type === 'date-picker') {
254
- defaultProps.valueFormat =
255
- item?.props?.type === 'datetime' ? 'YYYY-MM-DD HH:mm:ss' : 'YYYY-MM-DD';
200
+ defaultProps.valueFormat = item?.props?.type === 'datetime' ? 'YYYY-MM-DD HH:mm:ss' : 'YYYY-MM-DD';
256
201
  }
257
202
  // 如果配置了dictCode且存在对应的字典数据,设置options
258
203
  if (item.dictCode && dictData.value[item.dictCode]) {
259
204
  defaultProps.options = dictData.value[item.dictCode];
260
205
  }
261
206
  // 合并默认配置和自定义配置
262
- return { ...defaultProps, ...item.props };
207
+ return { ...defaultProps, ...(item?.props || {}) };
263
208
  }
264
209
 
265
210
  const formProps = computed(() => {
@@ -376,7 +321,7 @@ function isHide(item: FormColumnItem) {
376
321
  /** 禁用表单项 */
377
322
  function isDisabled(item: FormColumnItem) {
378
323
  if (item?.props?.disabled !== undefined) return item?.props?.disabled;
379
- if (props.fc?.[item.field]?.edit === false) return true;
324
+ if (props.fc?.[item.field]?.disabled === true) return true;
380
325
  return false;
381
326
  }
382
327
 
@@ -417,6 +362,7 @@ defineExpose({ formRef });
417
362
  }
418
363
 
419
364
  :deep(.hide-label) {
365
+
420
366
  // 隐藏el-form-item__label才能完整占满插槽宽度
421
367
  .el-form-item__label {
422
368
  display: none;
@@ -3,6 +3,7 @@ import type { FormProps as ElFormProps } from 'element-plus';
3
3
  import type { VNode } from 'vue';
4
4
  import type { GridItemProps, GridProps } from '../../grid/src/interface';
5
5
  import type { InputSearchInstance } from '../../input-search';
6
+ import type { MergeMultiple } from '../../../types/tool'
6
7
 
7
8
  export type FormColumnType =
8
9
  | 'input'
@@ -31,37 +32,45 @@ export type FormColumnType =
31
32
  | 'title'
32
33
  | 'slot';
33
34
 
34
- export type FormColumnProps = El.InputProps &
35
- El.InputNumberProps &
36
- El.InputTagProps &
37
- El.SelectProps &
38
- El.SelectV2Props &
39
- El.TreeInstance['$props'] &
40
- El.CascaderProps &
41
- El.SliderProps &
42
- El.SwitchProps &
43
- El.RateProps &
44
- El.CheckboxGroupProps &
45
- El.CheckboxProps &
46
- El.RadioGroupProps &
47
- El.RadioProps &
48
- El.DatePickerProps &
49
- El.TimePickerDefaultProps &
50
- El.TimeSelectProps &
51
- El.ColorPickerProps &
52
- El.TransferProps &
53
- El.AutocompleteProps &
54
- El.UploadProps &
55
- InputSearchInstance['$props'];
35
+ /**
36
+ * 表单列属性类型,根据组件类型使用对应的属性类型
37
+ */
38
+ export type FormColumnProps = MergeMultiple<[El.InputProps,
39
+ El.InputNumberProps,
40
+ El.InputTagProps,
41
+ El.SelectProps,
42
+ El.SelectV2Props,
43
+ El.TreeInstance['$props'],
44
+ El.CascaderProps,
45
+ El.SliderProps,
46
+ El.SwitchProps,
47
+ El.RateProps,
48
+ El.CheckboxGroupProps,
49
+ El.CheckboxProps,
50
+ El.RadioGroupProps,
51
+ El.RadioProps,
52
+ El.DatePickerProps,
53
+ El.TimePickerDefaultProps,
54
+ El.TimeSelectProps,
55
+ El.ColorPickerProps,
56
+ El.TransferProps,
57
+ El.AutocompleteProps,
58
+ El.UploadProps,
59
+ InputSearchInstance['$props']]>;
56
60
 
57
61
  export type FormColumnItemHide<F> = boolean | ((form: F) => boolean);
58
62
 
59
- export type FormColumnSlots = El.InputInstance['$slots'] &
60
- El.InputNumberInstance['$slots'] &
61
- El.InputTagInstance['$slots'] &
62
- El.AutocompleteInstance['$slots'] &
63
- El.CascaderInstance['$slots'] &
64
- El.DatePickerInstance['$slots'];
63
+ /**
64
+ * 表单列插槽类型,根据组件类型使用对应的插槽类型
65
+ */
66
+ export type FormColumnSlots = Partial<
67
+ El.InputInstance['$slots'] |
68
+ El.InputNumberInstance['$slots'] |
69
+ El.InputTagInstance['$slots'] |
70
+ El.AutocompleteInstance['$slots'] |
71
+ El.CascaderInstance['$slots'] |
72
+ El.DatePickerInstance['$slots']
73
+ >;
65
74
 
66
75
  export interface FormColumnItem<F = any> {
67
76
  type: FormColumnType;
@@ -70,9 +79,7 @@ export interface FormColumnItem<F = any> {
70
79
  field: string;
71
80
  fieldName?: string;
72
81
  span?: number;
73
- props?: FormColumnProps & {
74
- options?: El.RadioProps & El.CheckboxProps & El.SelectProps;
75
- };
82
+ props?: FormColumnProps;
76
83
  formItemProps?: El.FormItemProps;
77
84
  gridItemProps?: any;
78
85
  required?: boolean;
@@ -88,11 +95,11 @@ export interface FormColumnItem<F = any> {
88
95
  export interface FormProps extends Partial<ElFormProps> {
89
96
  modelValue: any;
90
97
  columns?: FormColumnItem[];
91
- fc?: Record<string, { edit: boolean; hidden?: boolean; required?: boolean }>; // 表单控制
98
+ fc?: Record<string, { disabled?: boolean; hidden?: boolean; required?: boolean }>; // 表单控制
92
99
  gridProps?: GridProps; // grid默认配置
93
100
  gridItemProps?: GridItemProps; // grid-item默认配置
94
101
  search?: boolean;
95
102
  searchText?: string;
96
103
  hideFoldBtn?: boolean;
97
104
  defaultCollapsed?: boolean | undefined;
98
- }
105
+ }
@@ -1,9 +1,4 @@
1
- import type {
2
- TableProps as ElTableProps,
3
- PaginationProps,
4
- TableColumnCtx,
5
- TableColumnInstance,
6
- } from 'element-plus';
1
+ import type { TableProps as ElTableProps, PaginationProps, TableColumnInstance } from 'element-plus';
7
2
  import type { ExtractPropTypes, VNode } from 'vue';
8
3
 
9
4
  type DefaultRow = Record<PropertyKey, any>
@@ -13,10 +8,7 @@ export interface TableColumnItem<T extends DefaultRow = DefaultRow> extends Omit
13
8
  render?: (scope: { $index: number; cellIndex: number; column: TableColumnItem<T>; row: T }) => VNode | VNode[] | string;
14
9
  }
15
10
 
16
- export interface TableProps
17
- extends ExtractPropTypes<
18
- ElTableProps<Record<string | number | symbol, any>>
19
- > {
11
+ export interface TableProps extends ExtractPropTypes<ElTableProps<Record<string | number | symbol, any>>> {
20
12
  columns?: TableColumnItem[];
21
13
  pagination?: Partial<PaginationProps>;
22
14
  }
@@ -2,19 +2,9 @@
2
2
  <div :class="getClass">
3
3
  <div :class="b('tabs__default')">
4
4
  <slot>
5
- <el-tabs
6
- v-model="model"
7
- :type="props.type"
8
- :stretch="props.stretch"
9
- @tab-click="(p, e) => emits('tabClick', p, e)"
10
- @tab-change="emits('tabChange', $event)"
11
- >
12
- <el-tab-pane
13
- v-for="item in props.options"
14
- :key="item.name"
15
- :name="item.name"
16
- :disabled="item?.disabled"
17
- >
5
+ <el-tabs v-model="model" :type="props.type" :stretch="props.stretch"
6
+ @tab-click="(p, e) => emits('tabClick', p, e)" @tab-change="emits('tabChange', $event as any)">
7
+ <el-tab-pane v-for="item in props.options" :key="item.name" :name="item.name" :disabled="item?.disabled">
18
8
  <template #label>
19
9
  <slot name="label" :data="item">{{ item.label }}</slot>
20
10
  </template>
@@ -113,7 +103,7 @@ const getClass = computed(() => {
113
103
  }
114
104
 
115
105
  :deep(.el-tabs--card) {
116
- > .el-tabs__header {
106
+ >.el-tabs__header {
117
107
  border-bottom: none;
118
108
  }
119
109
  }
@@ -121,11 +111,11 @@ const getClass = computed(() => {
121
111
  :deep(.el-tabs--border-card) {
122
112
  border-bottom: none;
123
113
 
124
- > .el-tabs__content {
114
+ >.el-tabs__content {
125
115
  display: none;
126
116
  }
127
117
 
128
- > .el-tabs__header {
118
+ >.el-tabs__header {
129
119
  border-bottom: none;
130
120
  }
131
121
  }
@@ -1,6 +1,6 @@
1
1
 
2
2
  import { ElMessageBox } from 'element-plus'
3
- import { reactive, ref, type Ref } from 'vue'
3
+ import { reactive, ref, getCurrentInstance, type Ref } from 'vue'
4
4
 
5
5
  interface Options<T, U> {
6
6
  onSuccess?: () => void
@@ -20,12 +20,18 @@ interface PageResult<T> {
20
20
  total: number
21
21
  }
22
22
 
23
- type Api<T> = (params: PaginationParams) => Promise<ApiResult<PageResult<T[]>>> | Promise<ApiResult<T[]>>
23
+ export interface UseTablePaginationParams { page: number; size: number; }
24
24
 
25
- interface PaginationParams { page: number; size: number; }
26
- export function useTable<T extends U, U = T>(api: Api<T>, options: Options<T, U>) {
25
+ export interface UseTableApi<T> {
26
+ (params: UseTablePaginationParams): Promise<ApiResult<PageResult<T[]>>> | Promise<ApiResult<T[]>>
27
+ }
28
+
29
+ export function useTable<T extends U, U = T>(api: UseTableApi<T>, options: Options<T, U>) {
27
30
  const { onSuccess, immediate = true, rowKey = 'id' } = options || {}
28
31
 
32
+ // const instance = getCurrentInstance();
33
+ // const globalConfig = instance?.appContext.config.globalProperties?.$config || {};
34
+
29
35
  const loading = ref(false)
30
36
  const tableData: Ref<U[]> = ref([])
31
37
 
package/packages/index.ts CHANGED
@@ -63,8 +63,12 @@ function capitalizeWord(word: string) {
63
63
  // 全局默认配置
64
64
  export interface Config {
65
65
  prefix?: string; // 组件前缀
66
- clearable?: boolean; // 输入框是否可清除
67
- dictRequest?: () => Promise<any>; // 字典请求方法
66
+ /** 输入框是否可清除 */
67
+ clearable?: boolean;
68
+ /** 字典请求方法 */
69
+ dictRequest?: () => Promise<any>;
70
+ /** 格式化响应数据, 用于useTable */
71
+ // formatResponse?: (data: any) => any;
68
72
  }
69
73
 
70
74
  export default {
@@ -5,8 +5,8 @@ body {
5
5
  --margin: 14px;
6
6
  --padding-x: 14px;
7
7
  --padding-x-small: 10px;
8
- --padding-y: 10px;
9
- --padding-y-small: 6px;
8
+ --padding-y: 12px;
9
+ --padding-y-small: 8px;
10
10
  }
11
11
 
12
12
  .gi-card-title {
@@ -170,6 +170,7 @@ body {
170
170
  .el-dialog__header {
171
171
  border-bottom: none;
172
172
  }
173
+
173
174
  .el-dialog__footer {
174
175
  border-top: none;
175
176
  }
@@ -0,0 +1,14 @@
1
+ // 辅助类型:获取所有类型的键的联合
2
+ type AllKeys<T> = T extends any ? keyof T : never;
3
+
4
+ // 辅助类型:获取属性在所有类型中的联合类型
5
+ type UnionType<T, K extends PropertyKey> = T extends any
6
+ ? K extends keyof T
7
+ ? T[K]
8
+ : never
9
+ : never;
10
+
11
+ // 合并多个类型,同名属性转为联合类型
12
+ export type MergeMultiple<T extends any[]> = {
13
+ [K in AllKeys<T[number]>]: UnionType<T[number], K>
14
+ };