@lx-frontend/wrap-element-ui 1.0.15 → 1.0.16-beta.0

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/README.md CHANGED
@@ -34,9 +34,9 @@ export default {
34
34
 
35
35
  ### 开发指南
36
36
 
37
- 新增或修改组件时,使用 `pnpm sb:dev` 可以实时预览 stories。
37
+ 新增或修改组件时,使用 `pnpm dev` 可以实时预览 stories。
38
38
 
39
- 开发完成后,可以使用 `pnpm sb:dist` 预览打包后的组件是否能正常工作。与 `pnpm sb:dev` 的区别在于,该命令修改了组件的引用地址,指向了打包后的组件。该命令不能实时预览修改。
39
+ 开发完成后,可以使用 `pnpm dist` 预览打包后的组件是否能正常工作。与 `pnpm dev` 的区别在于,该命令修改了组件的引用地址,指向了打包后的组件。该命令不能实时预览修改。
40
40
 
41
41
  `build:lib`命令用于打包组件库,生成组件代码及类型定义文件。
42
42
 
package/package.json CHANGED
@@ -1,14 +1,14 @@
1
1
  {
2
2
  "name": "@lx-frontend/wrap-element-ui",
3
- "version": "1.0.15",
3
+ "version": "1.0.16-beta.0",
4
4
  "description": "wrap-element-ui",
5
5
  "author": "",
6
6
  "main": "src/components/index.ts",
7
7
  "private": false,
8
8
  "scripts": {
9
9
  "clean": "rimraf dist",
10
- "sb:dev": "cross-env MODE=development storybook dev -p 6006",
11
- "sb:dist": "cross-env MODE=production pnpm build:lib && storybook dev -p 6006",
10
+ "dev": "cross-env MODE=development storybook dev -p 6006",
11
+ "dist": "cross-env MODE=production pnpm build:lib && storybook dev -p 6006",
12
12
  "build:lib": "pnpm clean && vite build",
13
13
  "build:sb": "cross-env MODE=production rimraf storybook-static && pnpm build:lib && storybook build",
14
14
  "preview": "serve ./storybook-static",
@@ -23,6 +23,7 @@
23
23
  "src/components"
24
24
  ],
25
25
  "peerDependencies": {
26
+ "dayjs": "^1.11.13",
26
27
  "element-ui": "^2.15.14",
27
28
  "lodash": "^4.17.21",
28
29
  "vue": "~2.7.16"
@@ -68,5 +69,8 @@
68
69
  "vite-plugin-lib-inject-css": "^2.1.1",
69
70
  "vite-tsconfig-paths": "^4.3.2",
70
71
  "vue-template-compiler": "^2.6.10"
72
+ },
73
+ "dependencies": {
74
+ "@lx-frontend/wrap-element-ui": "1.0.10"
71
75
  }
72
- }
76
+ }
@@ -1,5 +1,11 @@
1
1
  import { computed, nextTick, ref, Ref, watch } from 'vue'
2
- import { IColumnConfig, IEmits, IProps } from '../types';
2
+ import {
3
+ FilterListType,
4
+ IColumnConfig,
5
+ IEmits,
6
+ IFilterInput,
7
+ IProps
8
+ } from '../types';
3
9
 
4
10
  interface IUseColumnHeaderOperationParams {
5
11
  props: IProps
@@ -9,7 +15,6 @@ interface IUseColumnHeaderOperationParams {
9
15
  }
10
16
 
11
17
  export function useColumnHeaderOperation({ props, tableDomRef, emit, showingColumns }: IUseColumnHeaderOperationParams) {
12
-
13
18
  // column如果有sortable属性,点击列头部,会直接触发排序,为了在弹窗点确定时再触发排序,需要阻止点击立即排序
14
19
  // 所以,初始渲染时,将sortable设置为false,在触发排序逻辑时再设置成真实的值,再利用el-table自身的排序逻辑触发排序
15
20
  const inSorting = ref(false);
@@ -30,17 +35,19 @@ export function useColumnHeaderOperation({ props, tableDomRef, emit, showingColu
30
35
  const tempSummaryList = ref<string[]>([]);
31
36
  const summaryList = ref<string[]>([]);
32
37
 
33
- // 生效中的搜索配置 临时搜索配置
34
- const searchValue = ref<Record<string, string>>({});
35
- const tempSearchValue = ref<Record<string, string>>({});
36
-
37
- const isColumnFiltering = computed(() => Object.keys(tempFilteredValue.value).some(k => {
38
- const value = tempFilteredValue.value[k]
39
- if (!Array.isArray(value)) return value
40
- return value.length;
41
- }));
38
+ const isColumnFiltering = computed(() => {
39
+ return Object.keys(tempFilteredValue.value).some(
40
+ (key) => {
41
+ const value = tempFilteredValue.value[key]
42
+ if (Array.isArray(value)) return value.length
43
+ return value;
44
+ }
45
+ )
46
+ });
42
47
 
43
- const showColumnHeadSortIcon = (column: IColumnConfig) => column.filters || column.isColumnSortable || column.search || column.summary || column.doubleDatePicker;
48
+ const showColumnHeadSortIcon = ({ isColumnSortable, filters }: IColumnConfig) => {
49
+ return isColumnSortable || (filters && Array.isArray(filters) && filters.length > 0)
50
+ }
44
51
 
45
52
  watch(
46
53
  () => props.columnConfig,
@@ -72,41 +79,34 @@ export function useColumnHeaderOperation({ props, tableDomRef, emit, showingColu
72
79
  return sums
73
80
  }
74
81
 
75
- const isColumnHeadActive = (column: IColumnConfig) => {
76
- const hasPickerParams = !!(
77
- column.doubleDatePicker
78
- && (searchValue.value[column.doubleDatePicker.props[0]] || searchValue.value[column.doubleDatePicker.props[1]])
82
+ const isColumnHeadActive = ({ prop, filters, _sortable }: IColumnConfig) => {
83
+ const hasFilters = filters && Array.isArray(filters) && filters.length > 0
84
+ const currentFilterActive = hasFilters && filters?.some(
85
+ (item) => {
86
+ if (item.type === 'doubleDatePicker' || item.type === 'monthDayPicker') {
87
+ const [start, end] = item.prop
88
+ return !!(filteredValue.value[start] || filteredValue.value[end])
89
+ }
90
+
91
+ if (item.type === 'checkbox') {
92
+ return !!(filteredValue.value[item.prop] as any[]).length
93
+ }
94
+
95
+ return !!filteredValue.value[item.prop]
96
+ }
79
97
  )
80
98
 
81
- const isUseFilter = !!(column.filters && (Array.isArray(column.filters)
82
- ? (filteredValue.value[column.prop] as any[]).length
83
- : column.filters.type === 'radio'
84
- ? filteredValue.value[column.filters.prop || column.prop]
85
- : (filteredValue.value[column.filters.prop || column.prop] as any[]).length))
86
-
87
- const isUseSort = Array.isArray(column._sortable)
88
- ? column._sortable.some(v => v.prop === sortProp.value)
89
- : sortProp.value === column.prop
90
-
91
- const isUseSearch = Array.isArray(column.search)
92
- ? column.search?.some(v => {
93
- const props = typeof v.prop === 'string' ? [v.prop] : v.prop
94
- return props.some(p => searchValue.value[p])
95
- })
96
- : !!searchValue.value[column.prop]
97
-
98
- return isUseFilter
99
- || isUseSearch
100
- || hasPickerParams
101
- || isUseSort
102
- || summaryList.value.includes(column.prop);
99
+ const isUseSort = Array.isArray(_sortable)
100
+ ? _sortable.some(v => v.prop === sortProp.value)
101
+ : sortProp.value === prop
102
+
103
+ return currentFilterActive || isUseSort|| summaryList.value.includes(prop);
103
104
  }
104
105
 
105
106
  const handleHeaderPopoverShow = (column: IColumnConfig) => {
106
107
  // 关闭其他的排序和筛选弹窗(理论上不写也能关闭其他,但是就是有些列会出现两个弹窗同时出现的情况)
107
108
  closeSortAndFilterPopover(column.prop);
108
109
  tempFilteredValue.value = { ...filteredValue.value };
109
- tempSearchValue.value = { ...searchValue.value };
110
110
  tempSortType.value = sortType.value || '';
111
111
  tempSortProp.value = sortProp.value || '';
112
112
  // 临时合计项设置成实际的合计项
@@ -137,39 +137,33 @@ export function useColumnHeaderOperation({ props, tableDomRef, emit, showingColu
137
137
 
138
138
  const emitSearch = () => {
139
139
  const params: Record<string, any> = {};
140
- // 仅提交显示的列的相关数据
141
- showingColumns.value.forEach(prop => {
142
- const column = columnMap.value[prop]
143
- if (column.filters) {
144
- const _prop = (Array.isArray(column.filters) ? prop : column.filters.prop) || prop
145
- params[_prop] = filteredValue.value[_prop]
146
- }
147
- if (column.search) {
148
- if (Array.isArray(column.search)) {
149
- column.search.forEach(v => {
150
- const props = typeof v.prop === 'string' ? [v.prop] : v.prop
151
- props.forEach(p => {
152
- params[p] = searchValue.value[p]
153
- })
154
- })
140
+
141
+ const processFilter = (filters: FilterListType) => {
142
+ filters.forEach((item) => {
143
+ if (item.type === 'doubleDatePicker' || item.type === 'monthDayPicker') {
144
+ const [start, end] = item.prop
145
+ params[start] = filteredValue.value[start];
146
+ params[end] = filteredValue.value[end];
155
147
  } else {
156
- params[prop] = searchValue.value[prop]
148
+ params[item.prop] = filteredValue.value[item.prop];
157
149
  }
158
- }
159
- if (column.doubleDatePicker) {
160
- params[column.doubleDatePicker.props[0]] = searchValue.value[column.doubleDatePicker.props[0]]
161
- params[column.doubleDatePicker.props[1]] = searchValue.value[column.doubleDatePicker.props[1]]
162
- }
163
- })
150
+ });
151
+ }
152
+
153
+ // 仅提交显示的列的相关数据
154
+ showingColumns.value.forEach(prop => {
155
+ const { filters = [] } = columnMap.value[prop] as IColumnConfig;
156
+ processFilter(filters);
157
+ });
164
158
 
165
159
  if (props.colorFilterConfig) {
166
- const { prop } = props.colorFilterConfig
167
- params[prop] = filteredValue.value[prop]
160
+ const { filters = [] } = props.colorFilterConfig;
161
+ processFilter(filters);
168
162
  }
169
163
 
170
164
  Object.keys(params).forEach(key => {
171
- if (params[key] === undefined) delete params[key]
172
- })
165
+ if (params[key] === undefined) delete params[key];
166
+ });
173
167
 
174
168
  emit('search', {
175
169
  ...params,
@@ -177,33 +171,27 @@ export function useColumnHeaderOperation({ props, tableDomRef, emit, showingColu
177
171
  });
178
172
  };
179
173
 
180
- const handleHeaderOperationConfirm = async (column: IColumnConfig, scope) => {
181
- if (column.search) {
182
- // 校验
183
- if (Array.isArray(column.search)) {
184
- let validate = true;
185
- column.search.forEach(v => {
186
- if (!validate) return
187
- if (!('type' in v) || v.type === 'input') {
188
- if (!tempSearchValue.value[v.prop]) tempSearchValue.value[v.prop] = ''
189
- if (v.validator) {
190
- const result = v.validator(tempSearchValue.value[v.prop]?.trim());
191
- if (!result) validate = false;
192
- }
193
- } else if (v.type === 'doubleDatePicker' || v.type === 'slot') {
194
- if (v.validator) {
195
- const result = v.validator(tempSearchValue.value);
196
- if (!result) validate = false;
197
- }
198
- }
199
- })
200
- // 校验未通过
201
- if (!validate) return
202
- } else {
203
- if (!tempSearchValue.value[column.prop]) tempSearchValue.value[column.prop] = ''
204
- }
174
+
175
+ const handleHeaderOperationConfirm = async (column: IColumnConfig) => {
176
+ const inputFilters = (column.filters ?? []).filter(
177
+ (item): item is IFilterInput => item.type === 'input'
178
+ );
179
+
180
+ const hasValidatorError = inputFilters.some(
181
+ (item) => item.validator
182
+ && !item.validator((tempFilteredValue.value[item.prop] as string).trim())
183
+ )
184
+
185
+ if (hasValidatorError) {
186
+ return
205
187
  }
206
188
 
189
+ inputFilters.forEach(
190
+ (item) => {
191
+ if (!tempFilteredValue.value[item.prop]) tempFilteredValue.value[item.prop] = ''
192
+ }
193
+ )
194
+
207
195
  summaryList.value = [...tempSummaryList.value];
208
196
  sortProp.value = tempSortProp.value || '';
209
197
  sortType.value = tempSortType.value || null;
@@ -221,15 +209,8 @@ export function useColumnHeaderOperation({ props, tableDomRef, emit, showingColu
221
209
  }
222
210
 
223
211
  filteredValue.value = { ...tempFilteredValue.value };
224
- searchValue.value = Object.keys(tempSearchValue.value).reduce((pre, key) => {
225
- pre[key] = tempSearchValue.value[key]?.trim() ?? '';
226
- return pre;
227
- }, {});
228
212
 
229
213
  emitSearch();
230
-
231
- filterColumns(scope.store);
232
-
233
214
  closeSortAndFilterPopover();
234
215
  await nextTick()
235
216
  tableDomRef.value?.doLayout();
@@ -260,18 +241,27 @@ export function useColumnHeaderOperation({ props, tableDomRef, emit, showingColu
260
241
  }
261
242
 
262
243
  function handleResetFilterValue (column: IColumnConfig) {
263
- if (column.filters) {
264
- if (Array.isArray(column.filters)) {
265
- filteredValue.value[column.prop] = []
266
- } else if (column.filters.default) {
267
- filteredValue.value[column.filters.prop || column.prop] = column.filters.default
268
- } else {
269
- filteredValue.value[column.filters.prop || column.prop] = column.filters.type === 'radio' ? '' : []
270
- }
271
- }
244
+ (column.filters || [])
245
+ .forEach(
246
+ (item) => {
247
+ if (item.type === 'radio' || item.type === 'checkbox') {
248
+ if (item.defaultValue) {
249
+ filteredValue.value[item.prop] = item.defaultValue
250
+ } else {
251
+ filteredValue.value[item.prop] = item.type === 'radio' ? '' : []
252
+ }
253
+ } else if (item.type === 'doubleDatePicker' || item.type === 'monthDayPicker') {
254
+ const [start, end] = item.prop
255
+ filteredValue.value[start] = '';
256
+ filteredValue.value[end] = '';
257
+ } else {
258
+ filteredValue.value[item.prop] = ''
259
+ }
260
+ }
261
+ )
272
262
  }
273
263
 
274
- const handleHeaderOperationReset = async (column: IColumnConfig, scope) => {
264
+ const handleHeaderOperationReset = async (column: IColumnConfig) => {
275
265
  if (
276
266
  sortProp.value &&
277
267
  (Array.isArray(column._sortable)
@@ -285,94 +275,33 @@ export function useColumnHeaderOperation({ props, tableDomRef, emit, showingColu
285
275
  summaryList.value = summaryList.value.filter(item => item !== column.prop);
286
276
 
287
277
  handleResetFilterValue(column)
288
- if (column.search) {
289
- if (!Array.isArray(column.search)) {
290
- searchValue.value[column.prop] = '';
291
- } else {
292
- column.search.forEach(v => {
293
- const props = typeof v.prop === 'string' ? [v.prop] : v.prop
294
- props.forEach(p => {
295
- searchValue.value[p] = '';
296
- })
297
- })
298
- }
299
- }
300
- if (column.doubleDatePicker) {
301
- searchValue.value[column.doubleDatePicker.props[0]] = '';
302
- searchValue.value[column.doubleDatePicker.props[1]] = '';
303
- }
304
-
305
278
  emitSearch();
306
-
307
- filterColumns(scope.store);
308
-
309
279
  closeSortAndFilterPopover();
310
280
  await nextTick();
311
281
  tableDomRef.value?.doLayout();
312
282
  }
313
283
 
314
- const filterColumns = (store) => {
315
- if (!props.localFilter) return
316
- store.states.columns.forEach(column => {
317
- if (filteredValue.value[column.property]) {
318
- store.commit('filterChange', {
319
- column,
320
- values: filteredValue.value[column.property],
321
- });
322
- }
323
- });
324
-
325
- // 根据searchValue过滤数据
326
- const data = store.states.data.filter(item => {
327
- const flag = Object.keys(searchValue.value)
328
- .filter(key => searchValue.value[key])
329
- .reduce((pre, key) => {
330
- const value = searchValue.value[key];
331
-
332
- return pre && item[key] && `${item[key]}`.indexOf(value) > -1;
333
- }, true);
334
-
335
- return flag;
336
- });
337
-
338
- store.states.data = data;
339
- }
340
-
341
284
  const setSearchParams = (params: Record<string, any>) => {
342
- const _searchValue = {};
343
285
  const _filteredValue = {};
344
286
 
345
287
  // 设置搜索和过滤参数时,如果使用 showingColumns 遍历,会导致通过外部设置未显示的列的搜索和过滤参数丢失
346
- props.columnConfig.forEach(column => {
347
- if (column.search) {
348
- if (Array.isArray(column.search)) {
349
- column.search.forEach(v => {
350
- const props = typeof v.prop === 'string' ? [v.prop] : v.prop
351
- props.forEach(p => {
352
- _searchValue[p] = params[p];
353
- })
354
- });
355
- } else {
356
- _searchValue[column.prop] = params[column.prop] ?? '';
357
- }
358
- }
359
- if (column.filters) {
360
- const _prop = (Array.isArray(column.filters) ? column.prop : column.filters.prop) || column.prop
361
- const value = params[_prop] ?? (Array.isArray(column.filters) ? [] : column.filters.default);
362
- _filteredValue[_prop] = value;
363
- }
364
- if (column.doubleDatePicker) {
365
- _searchValue[column.doubleDatePicker.props[0]] = params[column.doubleDatePicker.props[0]] ?? '';
366
- _searchValue[column.doubleDatePicker.props[1]] = params[column.doubleDatePicker.props[1]] ?? '';
367
- }
288
+ [props.colorFilterConfig, ...props.columnConfig].forEach(column => {
289
+ (column?.filters ?? [])
290
+ .forEach(
291
+ (item) => {
292
+ if (item.type === 'doubleDatePicker' || item.type === 'monthDayPicker') {
293
+ const [start, end] = item.prop
294
+ _filteredValue[start] = params[start]
295
+ _filteredValue[end] = params[end]
296
+ } else if (item.type === 'checkbox') {
297
+ _filteredValue[item.prop] = params[item.prop] ?? item.defaultValue ?? []
298
+ } else {
299
+ _filteredValue[item.prop] = params[item.prop] ?? ''
300
+ }
301
+ }
302
+ )
368
303
  })
369
304
 
370
- if (props.colorFilterConfig) {
371
- const { prop, filters } = props.colorFilterConfig
372
- _filteredValue[prop] = params[prop] ?? (Array.isArray(filters) ? [] : filters?.default);
373
- }
374
-
375
- searchValue.value = { ...searchValue.value, ..._searchValue }
376
305
  filteredValue.value = { ...filteredValue.value, ..._filteredValue }
377
306
  }
378
307
 
@@ -390,13 +319,11 @@ export function useColumnHeaderOperation({ props, tableDomRef, emit, showingColu
390
319
  filteredValue,
391
320
  showColumnHeadSortIcon,
392
321
  tempSortProp,
393
- tempSearchValue,
394
322
  tempFilteredValue,
395
323
  tempSummaryList,
396
324
  tempSortType,
397
325
  sortProp,
398
326
  isColumnFiltering,
399
- searchValue,
400
327
  inSorting,
401
328
  }
402
329
  }
@@ -0,0 +1,40 @@
1
+ <!-- 复选框 -->
2
+ <template>
3
+ <div class="editable-table-sort-filter__filter">
4
+ <div class="editable-table-sort-filter__filter-title">
5
+ {{ config.label || '筛选' }}
6
+ </div>
7
+ <el-checkbox-group
8
+ class="editable-table-sort-filter__filter-checkbox-group"
9
+ :value="tempFilteredValue[config.prop]"
10
+ @input="val => emit('update:tempFilteredValue', config.prop, val)"
11
+ >
12
+ <el-checkbox
13
+ v-for="item in config.options"
14
+ :key="item.value"
15
+ :label="item.value"
16
+ :title="item.text"
17
+ class="editable-table-sort-filter__filter-checkbox"
18
+ >
19
+ {{ item.text }}
20
+ </el-checkbox>
21
+ </el-checkbox-group>
22
+ </div>
23
+ </template>
24
+
25
+ <script setup lang="ts">
26
+ import { IFilterSelect } from '../../types';
27
+
28
+ defineProps<{
29
+ config: IFilterSelect
30
+ tempFilteredValue: Record<string, string>
31
+ }>()
32
+
33
+ const emit = defineEmits<{
34
+ (e: 'update:tempFilteredValue', key: string, value: string): void
35
+ }>()
36
+ </script>
37
+
38
+ <style scoped lang="less">
39
+
40
+ </style>
@@ -0,0 +1,56 @@
1
+ <!-- 单选框 -->
2
+ <template>
3
+ <div class="editable-table-sort-filter__filter">
4
+ <div class="editable-table-sort-filter__filter-title">
5
+ {{ config.label || '筛选' }}
6
+ </div>
7
+ <el-radio-group
8
+ style="display: flex;flex-direction: column;gap: 6px;"
9
+ :value="tempFilteredValue[config.prop]"
10
+ @input="val => emit('update:tempFilteredValue', config.prop, val)"
11
+ >
12
+ <el-radio
13
+ v-for="item in config.options"
14
+ :key="item.value"
15
+ :label="item.value"
16
+ :title="item.text"
17
+ >
18
+ <span class="color-option">
19
+ <span
20
+ class="icon"
21
+ :style="{ background: item.color }"
22
+ />
23
+ <span>{{ item.text }}</span>
24
+ </span>
25
+ </el-radio>
26
+ </el-radio-group>
27
+ </div>
28
+ </template>
29
+
30
+ <script setup lang="ts">
31
+ import { IFilterColorRadio } from '../../types';
32
+
33
+ defineProps<{
34
+ config: IFilterColorRadio
35
+ tempFilteredValue: Record<string, string>
36
+ }>()
37
+
38
+ const emit = defineEmits<{
39
+ (e: 'update:tempFilteredValue', key: string, value: string): void
40
+ }>()
41
+ </script>
42
+
43
+ <style scoped lang="less">
44
+ .color-option {
45
+ display: flex;
46
+ align-items: center;
47
+
48
+ .icon {
49
+ border-radius: 50%;
50
+ width: 1em;
51
+ height: 1em;
52
+ margin-right: 0.3em;
53
+ border: 1px solid #ccc;
54
+ }
55
+ }
56
+ </style>
@@ -0,0 +1,91 @@
1
+ <!-- 日期范围选择(分开的两个日期选择器) -->
2
+ <template>
3
+ <div class="editable-table-sort-filter__sort">
4
+ <div class="editable-table-sort-filter__search-title">
5
+ {{ config.label || '筛选' }}
6
+ </div>
7
+ <div class="editable-table-sort-filter__date-picker-content">
8
+ <el-date-picker
9
+ v-bind="datePickerCommonProps"
10
+ placeholder="开始日期"
11
+ :value="tempFilteredValue[config.prop[0]]"
12
+ :picker-options="startDateDisabledOptions"
13
+ @input="handleStartDateChange"
14
+ />
15
+ <el-date-picker
16
+ v-bind="datePickerCommonProps"
17
+ placeholder="结束日期"
18
+ :value="tempFilteredValue[config.prop[1]]"
19
+ :picker-options="endDateDisabledOptions"
20
+ @input="handleEndDateChange"
21
+ />
22
+ </div>
23
+ </div>
24
+ </template>
25
+
26
+ <script setup lang="ts">
27
+ import { computed } from 'vue';
28
+ import { IFilterDoubleDatePicker } from '../../types';
29
+ import dayjs from 'dayjs';
30
+ import type { DatePickerOptions } from 'element-ui/types/date-picker';
31
+
32
+ interface IFilterDoubleDatePickerProps {
33
+ /** 日期选择器配置 */
34
+ config: IFilterDoubleDatePicker;
35
+ /** 临时筛选值 */
36
+ tempFilteredValue: Record<string, string>;
37
+ }
38
+
39
+ const props = defineProps<IFilterDoubleDatePickerProps>();
40
+
41
+ const emit = defineEmits<{
42
+ (e: 'update:tempFilteredValue', key: string, value: string): void;
43
+ }>();
44
+
45
+ /** 日期选择器通用配置 */
46
+ const datePickerCommonProps = {
47
+ valueFormat: 'yyyy-MM-dd',
48
+ format: 'yyyy-MM-dd',
49
+ type: 'date',
50
+ size: 'small',
51
+ editable: false,
52
+ } as const;
53
+
54
+ /** 开始日期禁用配置 */
55
+ const startDateDisabledOptions = computed<DatePickerOptions>(() => {
56
+ const endDate = props.tempFilteredValue[props.config.prop[1]];
57
+
58
+ return {
59
+ disabledDate: (time: Date) => {
60
+ if (!endDate) return false;
61
+
62
+ const currentDate = dayjs(time);
63
+ return currentDate.isAfter(dayjs(endDate), 'day');
64
+ }
65
+ };
66
+ });
67
+
68
+ /** 结束日期禁用配置 */
69
+ const endDateDisabledOptions = computed<DatePickerOptions>(() => {
70
+ const startDate = props.tempFilteredValue[props.config.prop[0]];
71
+
72
+ return {
73
+ disabledDate: (time: Date) => {
74
+ if (!startDate) return false;
75
+
76
+ const currentDate = dayjs(time);
77
+ return currentDate.isBefore(dayjs(startDate), 'day');
78
+ }
79
+ };
80
+ });
81
+
82
+ /** 处理开始日期变更 */
83
+ const handleStartDateChange = (val: string | null) => {
84
+ emit('update:tempFilteredValue', props.config.prop[0], val || '');
85
+ };
86
+
87
+ /** 处理结束日期变更 */
88
+ const handleEndDateChange = (val: string | null) => {
89
+ emit('update:tempFilteredValue', props.config.prop[1], val || '');
90
+ };
91
+ </script>
@@ -0,0 +1,26 @@
1
+ <template>
2
+ <div class="editable-table-sort-filter__search">
3
+ <div class="editable-table-sort-filter__search-title">
4
+ {{ config.label || '搜索' }}
5
+ </div>
6
+ <el-input
7
+ class="editable-table-sort-filter__search-input"
8
+ :placeholder="config.placeholder || '请输入内容'"
9
+ :value="tempFilteredValue[config.prop]"
10
+ @input="val => emit('update:tempFilteredValue', config.prop, val)"
11
+ />
12
+ </div>
13
+ </template>
14
+
15
+ <script setup lang="ts">
16
+ import { IFilterInput } from '../../types';
17
+
18
+ defineProps<{
19
+ config: IFilterInput
20
+ tempFilteredValue: Record<string, string>
21
+ }>()
22
+
23
+ const emit = defineEmits<{
24
+ (e: 'update:tempFilteredValue', key: string, value: string): void
25
+ }>()
26
+ </script>