@elementplus-kit/uikit 1.0.4 → 1.1.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/components/button/src/index.ts +163 -39
- package/components/button/style/index.scss +3 -0
- package/components/form/src/index.ts +10 -11
- package/components/search/src/index.tsx +202 -93
- package/components/search/style/index.scss +3 -1
- package/components/table/src/index.ts +2 -2
- package/package.json +1 -1
- package/components/search/src/index-/346/272/220.vue +0 -256
|
@@ -1,9 +1,16 @@
|
|
|
1
|
-
import { defineComponent, h } from "vue";
|
|
2
|
-
import {
|
|
1
|
+
import { defineComponent, h, PropType } from "vue";
|
|
2
|
+
import {
|
|
3
|
+
ElButton,
|
|
4
|
+
ElDropdown,
|
|
5
|
+
ElDropdownMenu,
|
|
6
|
+
ElDropdownItem,
|
|
7
|
+
buttonProps,
|
|
8
|
+
} from "element-plus";
|
|
3
9
|
|
|
4
|
-
|
|
10
|
+
import "../style/index.scss";
|
|
5
11
|
import { typeActiveMap } from "./constants.ts";
|
|
6
12
|
import { has, isBoolean, isFunction, isArray } from "lodash-es";
|
|
13
|
+
import { tr } from "element-plus/es/locales.mjs";
|
|
7
14
|
export default defineComponent({
|
|
8
15
|
props: {
|
|
9
16
|
params: {
|
|
@@ -15,8 +22,8 @@ export default defineComponent({
|
|
|
15
22
|
type: Array,
|
|
16
23
|
default: () => [],
|
|
17
24
|
},
|
|
18
|
-
//
|
|
19
|
-
|
|
25
|
+
// 权限验证函数
|
|
26
|
+
permit: {
|
|
20
27
|
type: Function,
|
|
21
28
|
},
|
|
22
29
|
size: {
|
|
@@ -35,6 +42,16 @@ export default defineComponent({
|
|
|
35
42
|
type: Boolean,
|
|
36
43
|
default: undefined,
|
|
37
44
|
},
|
|
45
|
+
// 折叠
|
|
46
|
+
fold: {
|
|
47
|
+
type: Boolean,
|
|
48
|
+
default: false,
|
|
49
|
+
},
|
|
50
|
+
// 折叠数量
|
|
51
|
+
foldNum: {
|
|
52
|
+
type: Number,
|
|
53
|
+
default: 0,
|
|
54
|
+
},
|
|
38
55
|
// // 权限函数
|
|
39
56
|
// hasRole: {
|
|
40
57
|
// type: Function,
|
|
@@ -46,31 +63,27 @@ export default defineComponent({
|
|
|
46
63
|
// console.log('slots', slots);
|
|
47
64
|
// console.log('attrs', attrs);
|
|
48
65
|
|
|
49
|
-
//
|
|
66
|
+
// 解析按钮属性
|
|
50
67
|
const getAttrs = (item) => {
|
|
51
68
|
let defaultAttrs = {
|
|
52
69
|
size: props.size,
|
|
53
70
|
plain: props.plain,
|
|
54
71
|
text: props.text,
|
|
55
72
|
link: props.link,
|
|
56
|
-
class: `c-alias-${item.alias || ""}`,
|
|
73
|
+
class: `c-btn-alias-${item.alias || ""}`,
|
|
57
74
|
};
|
|
58
75
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
}
|
|
76
|
+
// 默认按钮类型 用样式控制?
|
|
77
|
+
// if (item?.alias && typeActiveMap[item.alias]) {
|
|
78
|
+
// defaultAttrs = {
|
|
79
|
+
// ...typeActiveMap[item.alias],
|
|
80
|
+
// ...defaultAttrs,
|
|
81
|
+
// };
|
|
82
|
+
// }
|
|
65
83
|
|
|
66
84
|
// 过滤掉非elbutton属性
|
|
67
|
-
const filterAttrsList = [
|
|
68
|
-
|
|
69
|
-
"alias",
|
|
70
|
-
"permission",
|
|
71
|
-
"vIf",
|
|
72
|
-
"disable",
|
|
73
|
-
];
|
|
85
|
+
const filterAttrsList = ["label", "alias", "permit", "vIf", "disable"];
|
|
86
|
+
|
|
74
87
|
Object.keys(item).map((key) => {
|
|
75
88
|
if (!filterAttrsList.includes(key)) {
|
|
76
89
|
defaultAttrs[key] = item[key];
|
|
@@ -81,30 +94,55 @@ export default defineComponent({
|
|
|
81
94
|
if (isBoolean(item.disable)) {
|
|
82
95
|
defaultAttrs.disabled = item.disable;
|
|
83
96
|
}
|
|
84
|
-
if (
|
|
97
|
+
if (
|
|
98
|
+
isFunction(item.disable) &&
|
|
99
|
+
item.disable(props.params) !== undefined
|
|
100
|
+
) {
|
|
85
101
|
defaultAttrs.disabled = item.disable(props.params);
|
|
86
102
|
}
|
|
87
103
|
return defaultAttrs;
|
|
88
104
|
};
|
|
89
|
-
|
|
90
|
-
const
|
|
91
|
-
|
|
105
|
+
// 解析下拉菜单属性
|
|
106
|
+
const getDropdownAttrs = (item) => {
|
|
107
|
+
const obj = getAttrs(item);
|
|
108
|
+
const defaultAttrs = {
|
|
109
|
+
splitButton: true,
|
|
110
|
+
};
|
|
111
|
+
// 过滤下拉菜单属性
|
|
112
|
+
const l = [
|
|
113
|
+
"type",
|
|
114
|
+
"size",
|
|
115
|
+
"splitButton",
|
|
116
|
+
"disabled",
|
|
117
|
+
"placement",
|
|
118
|
+
"effect",
|
|
119
|
+
"trigger",
|
|
120
|
+
];
|
|
121
|
+
l.forEach((key) => {
|
|
122
|
+
if (obj[key] !== undefined) {
|
|
123
|
+
defaultAttrs[key] = obj[key];
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
return defaultAttrs;
|
|
127
|
+
};
|
|
128
|
+
// 过滤权限与 vIf
|
|
129
|
+
const filterOptions = () => {
|
|
130
|
+
const list = [];
|
|
92
131
|
// 过滤权限
|
|
93
132
|
props.btnOptions.map((item) => {
|
|
94
133
|
if (
|
|
95
|
-
isArray(item.
|
|
96
|
-
item.
|
|
97
|
-
isFunction(props.
|
|
134
|
+
isArray(item.permit) &&
|
|
135
|
+
item.permit.length > 0 &&
|
|
136
|
+
isFunction(props.permit)
|
|
98
137
|
) {
|
|
99
|
-
if (props.
|
|
138
|
+
if (props.permit(item.permit)) {
|
|
100
139
|
list.push(item);
|
|
101
140
|
}
|
|
102
141
|
} else {
|
|
103
142
|
list.push(item);
|
|
104
143
|
}
|
|
105
144
|
});
|
|
106
|
-
|
|
107
|
-
const listR = [];
|
|
145
|
+
const list2 = [];
|
|
108
146
|
// 过滤 vIf
|
|
109
147
|
list.map((item) => {
|
|
110
148
|
if (
|
|
@@ -113,27 +151,113 @@ export default defineComponent({
|
|
|
113
151
|
item.vIf(props.params) !== undefined
|
|
114
152
|
) {
|
|
115
153
|
if (item.vIf(props.params)) {
|
|
116
|
-
|
|
154
|
+
list2.push(item);
|
|
117
155
|
}
|
|
118
156
|
} else {
|
|
119
|
-
|
|
157
|
+
list2.push(item);
|
|
120
158
|
}
|
|
121
159
|
});
|
|
160
|
+
return list2;
|
|
161
|
+
};
|
|
162
|
+
// 按钮单个生成函数
|
|
163
|
+
const createBtn = (item) => {
|
|
164
|
+
return h(
|
|
165
|
+
ElButton,
|
|
166
|
+
{
|
|
167
|
+
...getAttrs(item),
|
|
168
|
+
onClick: () => {
|
|
169
|
+
emit("btnAction", item.alias, props.params);
|
|
170
|
+
},
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
default: () => item?.label,
|
|
174
|
+
}
|
|
175
|
+
);
|
|
176
|
+
};
|
|
177
|
+
// 下拉菜单生成函数
|
|
178
|
+
const createDropdown = (finalList) => {
|
|
179
|
+
const dropdownList = []; // 不折叠的按钮
|
|
180
|
+
const dropdownMain = []; // 下拉占位
|
|
181
|
+
const dropdownItemList = []; // 折叠的按钮
|
|
122
182
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
183
|
+
finalList.map((itm, idx) => {
|
|
184
|
+
if (idx < props.foldNum) {
|
|
185
|
+
dropdownList.push(itm);
|
|
186
|
+
} else if (idx === props.foldNum) {
|
|
187
|
+
dropdownMain.push(itm);
|
|
188
|
+
} else {
|
|
189
|
+
dropdownItemList.push(itm);
|
|
190
|
+
}
|
|
191
|
+
});
|
|
192
|
+
// 处理只有一个下拉按钮的情况
|
|
193
|
+
if (dropdownMain.length > 0 && dropdownItemList.length === 0) {
|
|
194
|
+
dropdownList.push(dropdownMain[0]);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// 最终渲染的vdom
|
|
198
|
+
let renderVdom = [];
|
|
199
|
+
// 展示按钮vdom
|
|
200
|
+
const butsVdom = dropdownList.map((item) => {
|
|
201
|
+
return createBtn(item);
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
// 合并参数
|
|
205
|
+
if (butsVdom.length > 0) {
|
|
206
|
+
renderVdom = renderVdom.concat(butsVdom);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
if (dropdownMain.length > 0 && dropdownItemList.length > 0) {
|
|
210
|
+
// 下拉菜单vdom
|
|
211
|
+
const dropdownVdom = h(
|
|
212
|
+
ElDropdown,
|
|
126
213
|
{
|
|
127
|
-
...
|
|
214
|
+
...getDropdownAttrs(dropdownMain[0]),
|
|
215
|
+
class: "c-btn-dropdown",
|
|
216
|
+
buttonProps: getAttrs(dropdownMain[0]),
|
|
217
|
+
splitButton: true,
|
|
218
|
+
// splitButton: dropdownItemList.length > 0,
|
|
128
219
|
onClick: () => {
|
|
129
|
-
emit("btnAction",
|
|
220
|
+
emit("btnAction", dropdownMain[0].alias, props.params);
|
|
221
|
+
},
|
|
222
|
+
onCommand: (command: string) => {
|
|
223
|
+
emit("btnAction", command, props.params);
|
|
130
224
|
},
|
|
131
225
|
},
|
|
132
226
|
{
|
|
133
|
-
default: () =>
|
|
227
|
+
default: () => {
|
|
228
|
+
return dropdownMain[0].label;
|
|
229
|
+
},
|
|
230
|
+
dropdown: () => {
|
|
231
|
+
return dropdownItemList.map((item) => {
|
|
232
|
+
return h(
|
|
233
|
+
ElDropdownItem,
|
|
234
|
+
{
|
|
235
|
+
command: item.alias,
|
|
236
|
+
},
|
|
237
|
+
{
|
|
238
|
+
default: () => item?.label,
|
|
239
|
+
}
|
|
240
|
+
);
|
|
241
|
+
});
|
|
242
|
+
},
|
|
134
243
|
}
|
|
135
244
|
);
|
|
136
|
-
|
|
245
|
+
renderVdom = renderVdom.concat(dropdownVdom);
|
|
246
|
+
}
|
|
247
|
+
return renderVdom;
|
|
248
|
+
};
|
|
249
|
+
|
|
250
|
+
const render = () => {
|
|
251
|
+
const finalList = filterOptions(); // 最终列表
|
|
252
|
+
// 是否折叠 折叠
|
|
253
|
+
if (props.fold) {
|
|
254
|
+
return createDropdown(finalList);
|
|
255
|
+
} else {
|
|
256
|
+
// 不折叠
|
|
257
|
+
return finalList.map((item) => {
|
|
258
|
+
return createBtn(item);
|
|
259
|
+
});
|
|
260
|
+
}
|
|
137
261
|
};
|
|
138
262
|
return () => render();
|
|
139
263
|
},
|
|
@@ -14,7 +14,7 @@ import zhCn from "element-plus/es/locale/lang/zh-cn";
|
|
|
14
14
|
import CFormItem from "./FormItem.ts";
|
|
15
15
|
import { has, isArray, isBoolean, isFunction, isNumber } from "lodash-es";
|
|
16
16
|
import { getEmits } from "./constants"; // 获取所有的事件
|
|
17
|
-
import
|
|
17
|
+
import "../style/index.scss";
|
|
18
18
|
const propsAttrs = {
|
|
19
19
|
// 表单数据
|
|
20
20
|
model: { type: Object, default: () => ({}) },
|
|
@@ -60,7 +60,7 @@ export default defineComponent({
|
|
|
60
60
|
});
|
|
61
61
|
|
|
62
62
|
// 解构props
|
|
63
|
-
const { model, formOptions, readonly, gutter, col} = toRefs(props);
|
|
63
|
+
const { model, formOptions, readonly, gutter, col } = toRefs(props);
|
|
64
64
|
|
|
65
65
|
// 暴露elForm组件上的方法
|
|
66
66
|
const vm = getCurrentInstance(); // 获取虚拟DOM实例
|
|
@@ -105,18 +105,18 @@ export default defineComponent({
|
|
|
105
105
|
// 渲染表单项
|
|
106
106
|
const renderFormItem = () => {
|
|
107
107
|
// 过滤权限
|
|
108
|
-
const list = []
|
|
108
|
+
const list = [];
|
|
109
109
|
formOptions.value.map((item) => {
|
|
110
|
-
// 处理 vIf
|
|
111
|
-
if(
|
|
112
|
-
if (
|
|
113
|
-
list.push(item)
|
|
110
|
+
// 处理 vIf true 显示 false 隐藏
|
|
111
|
+
if (isFunction(item?.vIf) && item.vIf(props.model, props.params) !== undefined) {
|
|
112
|
+
if (item.vIf(props.model, props.params)) {
|
|
113
|
+
list.push(item);
|
|
114
114
|
}
|
|
115
115
|
} else {
|
|
116
|
-
list.push(item)
|
|
116
|
+
list.push(item);
|
|
117
117
|
}
|
|
118
|
-
})
|
|
119
|
-
return
|
|
118
|
+
});
|
|
119
|
+
return list.map((item) => {
|
|
120
120
|
// const { label, prop, type, required, col, formItem, attrs } = item
|
|
121
121
|
// const { label, prop, type, required, col, formItem, attrs, ...args } = item
|
|
122
122
|
const rFormItem = () => {
|
|
@@ -170,7 +170,6 @@ export default defineComponent({
|
|
|
170
170
|
|
|
171
171
|
// 渲染表单
|
|
172
172
|
const renderForm = () => {
|
|
173
|
-
console.log('$attrs', $attrs);
|
|
174
173
|
return h(
|
|
175
174
|
ElConfigProvider,
|
|
176
175
|
{
|
|
@@ -1,35 +1,29 @@
|
|
|
1
|
-
import {
|
|
2
|
-
ref,
|
|
3
|
-
computed,
|
|
4
|
-
defineComponent,
|
|
5
|
-
} from "vue";
|
|
1
|
+
import { ref, defineComponent, onMounted, onUnmounted, nextTick } from "vue";
|
|
6
2
|
|
|
7
3
|
import { CForm, CDrawer } from "@elementplus-kit/uikit";
|
|
8
4
|
import { ArrowUpBold } from "@element-plus/icons-vue";
|
|
9
|
-
import
|
|
5
|
+
import "../style/index.scss";
|
|
10
6
|
|
|
11
7
|
export default defineComponent({
|
|
12
8
|
props: {
|
|
13
9
|
modelValue: {
|
|
14
10
|
type: Object,
|
|
15
|
-
default: {}
|
|
11
|
+
default: {},
|
|
16
12
|
},
|
|
17
13
|
formOptions: {
|
|
18
14
|
type: Array,
|
|
19
|
-
default: () => []
|
|
15
|
+
default: () => [],
|
|
20
16
|
},
|
|
21
17
|
isDrawer: {
|
|
22
18
|
type: Boolean,
|
|
23
|
-
default: false
|
|
19
|
+
default: false,
|
|
24
20
|
},
|
|
25
21
|
},
|
|
26
|
-
emits: [
|
|
22
|
+
emits: ["update:modelValue", "search", "reset", "close"],
|
|
27
23
|
|
|
28
24
|
setup(props, { emit, slots, attrs, expose }) {
|
|
29
25
|
// 自己的 slot
|
|
30
26
|
const slotsList = ["active", "btn-left", "btn-right"];
|
|
31
|
-
// console.log('slots', slots);
|
|
32
|
-
// console.log('attrs', attrs);
|
|
33
27
|
// 解析 attrs 中的事件
|
|
34
28
|
const getEvent = () => {
|
|
35
29
|
let formObj: any = {};
|
|
@@ -37,8 +31,8 @@ export default defineComponent({
|
|
|
37
31
|
if (name.indexOf("on") === 0) {
|
|
38
32
|
formObj[name] = attrs[name];
|
|
39
33
|
}
|
|
40
|
-
})
|
|
41
|
-
return formObj
|
|
34
|
+
});
|
|
35
|
+
return formObj;
|
|
42
36
|
};
|
|
43
37
|
|
|
44
38
|
// 解析插槽
|
|
@@ -49,13 +43,14 @@ export default defineComponent({
|
|
|
49
43
|
formObj[key] = slots[key];
|
|
50
44
|
}
|
|
51
45
|
});
|
|
52
|
-
return formObj
|
|
46
|
+
return formObj;
|
|
53
47
|
};
|
|
54
48
|
|
|
55
49
|
// 搜索
|
|
56
50
|
const handleSearch = () => {
|
|
57
51
|
emit("search");
|
|
58
52
|
showSearchForm.value = false;
|
|
53
|
+
document.removeEventListener("click", handleClickOutside); // 销毁点击事件
|
|
59
54
|
};
|
|
60
55
|
// 重置
|
|
61
56
|
const handleReset = () => {
|
|
@@ -64,65 +59,203 @@ export default defineComponent({
|
|
|
64
59
|
// 关闭
|
|
65
60
|
const handleClose = () => {
|
|
66
61
|
showSearchForm.value = false;
|
|
62
|
+
document.removeEventListener("click", handleClickOutside); // 销毁点击事件
|
|
67
63
|
emit("close");
|
|
68
64
|
};
|
|
65
|
+
// 点击元素外关闭
|
|
66
|
+
const dropdownRef = ref<HTMLElement | null>(null); // 下拉表单的 ref
|
|
67
|
+
// 判断点击事件是否在 targetElement 外部
|
|
68
|
+
const isClickOutside = (event, targetElement) => {
|
|
69
|
+
console.log("🚀 ~ isClickOutside ~ targetElement:", targetElement);
|
|
70
|
+
return !targetElement.contains(event.target);
|
|
71
|
+
};
|
|
72
|
+
// 点击外部关闭函数
|
|
73
|
+
const handleClickOutside = (event: MouseEvent) => {
|
|
74
|
+
// 如果下拉表单可见,且点击事件不在下拉表单内部
|
|
75
|
+
if (
|
|
76
|
+
showSearchForm.value &&
|
|
77
|
+
dropdownRef.value &&
|
|
78
|
+
!dropdownRef.value?.$el?.contains(event.target)
|
|
79
|
+
) {
|
|
80
|
+
showSearchForm.value = false; // 关闭下拉表单
|
|
81
|
+
document.removeEventListener("click", handleClickOutside); // 销毁点击事件
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
// 显示隐藏折叠搜索表单
|
|
85
|
+
const showSearchForm = ref(false);
|
|
86
|
+
const handleShow = () => {
|
|
87
|
+
if (showSearchForm.value) {
|
|
88
|
+
showSearchForm.value = false;
|
|
89
|
+
document.removeEventListener("click", handleClickOutside); // 销毁点击事件
|
|
90
|
+
} else {
|
|
91
|
+
showSearchForm.value = true;
|
|
92
|
+
setTimeout(() => {
|
|
93
|
+
document.addEventListener("click", handleClickOutside); // 注册点击事件
|
|
94
|
+
}, 0);
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
const showCount = ref(6); // 显示个数
|
|
99
|
+
const searchRef = ref<HTMLDivElement>(null);
|
|
100
|
+
const cFormRef = ref<HTMLDivElement>(null);
|
|
101
|
+
const calcFlg = ref(false); // 计算宽度后再显示表单
|
|
102
|
+
const childW = ref([]);
|
|
69
103
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
104
|
+
// 设置节流
|
|
105
|
+
let timer: any = null;
|
|
106
|
+
const searchResize = () => {
|
|
107
|
+
if (timer) {
|
|
108
|
+
clearTimeout(timer);
|
|
109
|
+
}
|
|
110
|
+
timer = setTimeout(() => {
|
|
111
|
+
calcSunResize();
|
|
112
|
+
}, 200);
|
|
113
|
+
};
|
|
73
114
|
|
|
74
|
-
|
|
75
|
-
const
|
|
76
|
-
|
|
77
|
-
|
|
115
|
+
// 初次计算显示个数
|
|
116
|
+
const calcSunInit = () => {
|
|
117
|
+
if (searchRef.value) {
|
|
118
|
+
// 寻找cForm 先写死 后期做成动态寻找
|
|
119
|
+
const cFormDom = searchRef.value.children[0];
|
|
120
|
+
const cFormW = cFormDom.offsetWidth;
|
|
121
|
+
// 收集子元素宽度并保存到数组中
|
|
122
|
+
const cW = [];
|
|
123
|
+
// const marginR = [];
|
|
124
|
+
Array.from(cFormDom.children).map((child) => {
|
|
125
|
+
const computedStyles = window.getComputedStyle(child); // 获取元素 css 样式
|
|
126
|
+
const mg = computedStyles.marginRight; // 获取元素 margin-right 样式值 有单位
|
|
127
|
+
const mgValue = parseFloat(mg); // 转换为数值
|
|
128
|
+
// marginR.push(mgValue);
|
|
129
|
+
cW.push(child.offsetWidth + mgValue); // 把mg加上 mg 一般不会变 为了避免多次计算
|
|
130
|
+
});
|
|
131
|
+
childW.value = cW;
|
|
132
|
+
childW.value.reduce((pre, cur, index) => {
|
|
133
|
+
if (pre > cFormW) {
|
|
134
|
+
return 10000; // 终止累加
|
|
135
|
+
}
|
|
136
|
+
if (pre + cur > cFormW) {
|
|
137
|
+
showCount.value = index;
|
|
138
|
+
return pre + cur;
|
|
139
|
+
}
|
|
140
|
+
return pre + cur;
|
|
141
|
+
}, 0);
|
|
142
|
+
|
|
143
|
+
// 得到结果后 显示表单
|
|
144
|
+
calcFlg.value = true;
|
|
145
|
+
// offsetWidth
|
|
146
|
+
// clientWidth
|
|
147
|
+
// classList
|
|
148
|
+
}
|
|
78
149
|
};
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
150
|
+
// 变化时计算显示个数
|
|
151
|
+
const calcSunResize = () => {
|
|
152
|
+
if (searchRef.value) {
|
|
153
|
+
// 寻找cForm 先写死 后期做成动态寻找
|
|
154
|
+
const cFormDom = searchRef.value.children[0];
|
|
155
|
+
const cFormW = cFormDom.offsetWidth;
|
|
156
|
+
childW.value.reduce((pre, cur, index) => {
|
|
157
|
+
if (pre > cFormW) {
|
|
158
|
+
return 10000; // 终止累加
|
|
159
|
+
}
|
|
160
|
+
if (pre + cur > cFormW) {
|
|
161
|
+
showCount.value = index;
|
|
162
|
+
return pre + cur;
|
|
163
|
+
}
|
|
164
|
+
return pre + cur;
|
|
165
|
+
}, 0);
|
|
166
|
+
}
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
onMounted(() => {
|
|
170
|
+
// 初始化执行一次
|
|
171
|
+
calcSunInit();
|
|
172
|
+
// 注册页面大小函数
|
|
173
|
+
window.addEventListener("resize", searchResize);
|
|
174
|
+
});
|
|
175
|
+
// 销毁
|
|
176
|
+
onUnmounted(() => {
|
|
177
|
+
window.removeEventListener("resize", searchResize);
|
|
178
|
+
document.removeEventListener("click", handleClickOutside); // 销毁点击事件
|
|
179
|
+
});
|
|
180
|
+
return () => {
|
|
181
|
+
return (
|
|
182
|
+
<div className="c-search">
|
|
183
|
+
<div
|
|
184
|
+
className="c-search-simple"
|
|
185
|
+
style={calcFlg.value ? "" : "opacity: 0;"}
|
|
186
|
+
>
|
|
187
|
+
<div className="c-search-simple-form" ref={searchRef}>
|
|
188
|
+
<CForm
|
|
189
|
+
ref={(el) => (cFormRef.value = el)}
|
|
190
|
+
{...getEvent()}
|
|
191
|
+
inline
|
|
192
|
+
model={props.modelValue}
|
|
193
|
+
formOptions={props.formOptions?.filter(
|
|
194
|
+
(item, index) => index < showCount.value
|
|
195
|
+
)}
|
|
196
|
+
>
|
|
197
|
+
{getSlot()}
|
|
198
|
+
</CForm>
|
|
199
|
+
</div>
|
|
200
|
+
<div className="c-search-simple-btn">
|
|
201
|
+
{slots["btn-left"]?.()}
|
|
202
|
+
{showCount.value < props.formOptions?.length && (
|
|
203
|
+
<div
|
|
204
|
+
className={`c-search-simple-icon ${
|
|
205
|
+
showSearchForm.value ? "icon-rotate" : ""
|
|
206
|
+
}`}
|
|
207
|
+
onClick={handleShow}
|
|
208
|
+
>
|
|
209
|
+
<el-icon className="el-icon c-search-icon">
|
|
210
|
+
<ArrowUpBold />
|
|
211
|
+
</el-icon>
|
|
212
|
+
</div>
|
|
89
213
|
)}
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
214
|
+
<el-button type="primary" onClick={handleSearch}>
|
|
215
|
+
搜索
|
|
216
|
+
</el-button>
|
|
217
|
+
<el-button type="primary" onClick={handleReset}>
|
|
218
|
+
重置
|
|
219
|
+
</el-button>
|
|
220
|
+
{slots["btn-right"]?.()}
|
|
221
|
+
</div>
|
|
94
222
|
</div>
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
onClick={handleShow}
|
|
223
|
+
|
|
224
|
+
{/* 下拉悬浮 */}
|
|
225
|
+
{!props.isDrawer && showSearchForm.value && (
|
|
226
|
+
<transition name="search-form-transition">
|
|
227
|
+
<el-card
|
|
228
|
+
ref={dropdownRef}
|
|
229
|
+
className="c-search-form el-card is-always-shadow"
|
|
103
230
|
>
|
|
104
|
-
<
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
231
|
+
<CForm
|
|
232
|
+
{...getEvent()}
|
|
233
|
+
inline
|
|
234
|
+
model={props.modelValue}
|
|
235
|
+
formOptions={props.formOptions.filter(
|
|
236
|
+
(item, index) => index >= showCount.value
|
|
237
|
+
)}
|
|
238
|
+
ref="formRef"
|
|
239
|
+
>
|
|
240
|
+
{getSlot()}
|
|
241
|
+
</CForm>
|
|
242
|
+
<div style="text-align: right;">
|
|
243
|
+
<el-button type="primary" onClick={handleSearch}>
|
|
244
|
+
搜索
|
|
245
|
+
</el-button>
|
|
246
|
+
<el-button type="primary" onClick={handleClose}>
|
|
247
|
+
关闭
|
|
248
|
+
</el-button>
|
|
249
|
+
</div>
|
|
250
|
+
</el-card>
|
|
251
|
+
</transition>
|
|
252
|
+
)}
|
|
118
253
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
<transition name="search-form-transition">
|
|
122
|
-
<el-card className="c-search-form el-card is-always-shadow">
|
|
254
|
+
{props.isDrawer && (
|
|
255
|
+
<CDrawer title="搜索" v-model={showSearchForm.value} size="660px">
|
|
123
256
|
<CForm
|
|
124
257
|
{...getEvent()}
|
|
125
|
-
|
|
258
|
+
col={12}
|
|
126
259
|
model={props.modelValue}
|
|
127
260
|
formOptions={props.formOptions.filter(
|
|
128
261
|
(item, index) => index >= showCount.value
|
|
@@ -139,34 +272,10 @@ export default defineComponent({
|
|
|
139
272
|
关闭
|
|
140
273
|
</el-button>
|
|
141
274
|
</div>
|
|
142
|
-
</
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
<CDrawer title="搜索" v-model={showSearchForm.value} size="660px">
|
|
148
|
-
<CForm
|
|
149
|
-
{...getEvent()}
|
|
150
|
-
col={12}
|
|
151
|
-
model={props.modelValue}
|
|
152
|
-
formOptions={props.formOptions.filter(
|
|
153
|
-
(item, index) => index >= showCount.value
|
|
154
|
-
)}
|
|
155
|
-
ref="formRef"
|
|
156
|
-
>
|
|
157
|
-
{getSlot()}
|
|
158
|
-
</CForm>
|
|
159
|
-
<div style="text-align: right;">
|
|
160
|
-
<el-button type="primary" onClick={handleSearch}>
|
|
161
|
-
搜索
|
|
162
|
-
</el-button>
|
|
163
|
-
<el-button type="primary" onClick={handleClose}>
|
|
164
|
-
关闭
|
|
165
|
-
</el-button>
|
|
166
|
-
</div>
|
|
167
|
-
</CDrawer>
|
|
168
|
-
)}
|
|
169
|
-
</div>
|
|
170
|
-
)
|
|
275
|
+
</CDrawer>
|
|
276
|
+
)}
|
|
277
|
+
</div>
|
|
278
|
+
);
|
|
279
|
+
};
|
|
171
280
|
},
|
|
172
|
-
})
|
|
281
|
+
});
|
|
@@ -132,11 +132,11 @@ export default defineComponent({
|
|
|
132
132
|
const rColumn = (columns, list) => {
|
|
133
133
|
columns.map((item) => {
|
|
134
134
|
const { children, ...p } = item;
|
|
135
|
-
// 处理 vIf
|
|
135
|
+
// 处理 vIf true 显示 false 隐藏
|
|
136
136
|
if (
|
|
137
137
|
isFunction(item.vIf) &&
|
|
138
138
|
item.vIf(props.params) !== undefined &&
|
|
139
|
-
item.vIf(props.params)
|
|
139
|
+
!item.vIf(props.params)
|
|
140
140
|
) {
|
|
141
141
|
return;
|
|
142
142
|
}
|
package/package.json
CHANGED
|
@@ -1,256 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<div class="c-search">
|
|
3
|
-
<div class="c-search-simple">
|
|
4
|
-
<div class="c-search-simple-form">
|
|
5
|
-
<c-form v-bind="getEvent(), getSlot('form')" inline :model="formData"
|
|
6
|
-
:formOptions="props.formOptions.filter((item, index) => index < showCount)" ref="formRef">
|
|
7
|
-
<template #[`c-search-button`]>
|
|
8
|
-
<slot name="active"></slot>
|
|
9
|
-
</template>
|
|
10
|
-
</c-form>
|
|
11
|
-
</div>
|
|
12
|
-
<div class="c-search-simple-btn">
|
|
13
|
-
<slot name="btn-left" />
|
|
14
|
-
<div class="c-search-simple-icon" @click="handleShow" v-if="showCount < props.formOptions.length"
|
|
15
|
-
:class="{ 'icon-rotate': showSearchForm }">
|
|
16
|
-
<el-icon class="c-search-icon">
|
|
17
|
-
<ArrowUpBold />
|
|
18
|
-
</el-icon>
|
|
19
|
-
</div>
|
|
20
|
-
<el-button type="primary" @click="handleSearch">搜索</el-button>
|
|
21
|
-
<el-button type="primary" @click="handleReset">重置</el-button>
|
|
22
|
-
<slot name="btn-right" />
|
|
23
|
-
</div>
|
|
24
|
-
</div>
|
|
25
|
-
<!-- 下拉悬浮 -->
|
|
26
|
-
<transition name="search-form-transition">
|
|
27
|
-
<el-card class="c-search-form" v-if="showSearchForm && props.isDrawer">
|
|
28
|
-
<c-form v-bind="getEvent(), getSlot('form')"" inline :model="formData"
|
|
29
|
-
:formOptions="props.formOptions.filter((item, index) => index >= showCount)" ref="formRef">
|
|
30
|
-
</c-form>
|
|
31
|
-
<div style="text-align: right;">
|
|
32
|
-
<el-button type="primary" @click="handleSearch">搜索</el-button>
|
|
33
|
-
<el-button type="primary" @click="handleClose">关闭</el-button>
|
|
34
|
-
</div>
|
|
35
|
-
</el-card>
|
|
36
|
-
</transition>
|
|
37
|
-
<c-drawer v-if="!props.isDrawer" title="搜索" v-model="showSearchForm" size="660px">
|
|
38
|
-
<c-form v-bind="getEvent(), getSlot('form')" :col="12" :model="formData"
|
|
39
|
-
:formOptions="props.formOptions.filter((item, index) => index >= showCount)" ref="formRef">
|
|
40
|
-
</c-form>
|
|
41
|
-
<div style="text-align: right;">
|
|
42
|
-
<el-button type="primary" @click="handleSearch">搜索</el-button>
|
|
43
|
-
<el-button type="primary" @click="handleClose">关闭</el-button>
|
|
44
|
-
</div>
|
|
45
|
-
</c-drawer>
|
|
46
|
-
</div>
|
|
47
|
-
</template>
|
|
48
|
-
<script setup lang="ts">
|
|
49
|
-
import { ref, computed, useAttrs, useSlots, defineModel } from 'vue'
|
|
50
|
-
import { CForm, CDrawer } from '@elementplus-kit/uikit'
|
|
51
|
-
import { ArrowUpBold } from '@element-plus/icons-vue'
|
|
52
|
-
const props = defineProps({
|
|
53
|
-
formOptions: {
|
|
54
|
-
type: Array,
|
|
55
|
-
default: () => []
|
|
56
|
-
},
|
|
57
|
-
formItemButton: {
|
|
58
|
-
type: Object,
|
|
59
|
-
default: () => ({
|
|
60
|
-
label: '',
|
|
61
|
-
prop: 'c-button',
|
|
62
|
-
})
|
|
63
|
-
},
|
|
64
|
-
isDrawer: {
|
|
65
|
-
type: Boolean,
|
|
66
|
-
default: true
|
|
67
|
-
},
|
|
68
|
-
showCount: { // 显示简洁栏的个数
|
|
69
|
-
type: Number,
|
|
70
|
-
default: 3
|
|
71
|
-
}
|
|
72
|
-
})
|
|
73
|
-
const emit = defineEmits(['search', 'reset', 'close'])
|
|
74
|
-
|
|
75
|
-
const formData = defineModel()
|
|
76
|
-
const attr = useAttrs()
|
|
77
|
-
const slots = useSlots()
|
|
78
|
-
|
|
79
|
-
// 自己的 slot
|
|
80
|
-
const slotsMap = ['active']
|
|
81
|
-
// 解析 attr 中的事件
|
|
82
|
-
const getEvent = (name: string) => {
|
|
83
|
-
let obj = {}
|
|
84
|
-
Object.keys(attr).forEach(key => {
|
|
85
|
-
if (key.startsWith('on')) {
|
|
86
|
-
obj[key] = attr[key]
|
|
87
|
-
}
|
|
88
|
-
})
|
|
89
|
-
return obj
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
// 解析插槽
|
|
93
|
-
const getSlot = (type: 'form' | 'search') => {
|
|
94
|
-
let searchObj: any = {}
|
|
95
|
-
let formObj: any = {}
|
|
96
|
-
Object.keys(slots).forEach(key => {
|
|
97
|
-
if (slotsMap.includes(key)) {
|
|
98
|
-
searchObj[key] = slots[key]
|
|
99
|
-
} else {
|
|
100
|
-
formObj[key] = slots[key]
|
|
101
|
-
}
|
|
102
|
-
})
|
|
103
|
-
return type === 'search' ? formObj : searchObj
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
const handleSearch = () => {
|
|
107
|
-
emit('search')
|
|
108
|
-
showSearchForm.value = false
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
const handleReset = () => {
|
|
112
|
-
emit('reset')
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
const handleClose = () => {
|
|
116
|
-
showSearchForm.value = false
|
|
117
|
-
emit('close')
|
|
118
|
-
}
|
|
119
|
-
const showCountC = computed(() => {
|
|
120
|
-
return props.showCount
|
|
121
|
-
})
|
|
122
|
-
|
|
123
|
-
const showCount = ref(3) // 显示个数
|
|
124
|
-
const showSearchForm = ref(false) // 显示搜索表单
|
|
125
|
-
const handleShow = () => {
|
|
126
|
-
showSearchForm.value = !showSearchForm.value
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
// const formOptionsSimple = computed(() => {
|
|
130
|
-
// // 取3为简洁栏
|
|
131
|
-
// const l = props.formOptions?.slice(0, 3)
|
|
132
|
-
// l.push(props.formItemButton)
|
|
133
|
-
// formOptionsHidden.value = props.formOptions?.slice(3)
|
|
134
|
-
// return l
|
|
135
|
-
// })
|
|
136
|
-
|
|
137
|
-
// // const formOptionsSimple = ref([]) // 简洁栏
|
|
138
|
-
// // const formOptionsHidden = ref([]) // 隐藏栏
|
|
139
|
-
|
|
140
|
-
// 窗口大小变化时,调整搜索表单的宽度
|
|
141
|
-
// const handleResize = () => {
|
|
142
|
-
// if (window.innerWidth <= 768) {
|
|
143
|
-
// formOptions.value.forEach(item => {
|
|
144
|
-
// item.col = {
|
|
145
|
-
// span: 24
|
|
146
|
-
// }
|
|
147
|
-
// })
|
|
148
|
-
// } else {
|
|
149
|
-
// formOptions.value.forEach(item => {
|
|
150
|
-
// item.col = {
|
|
151
|
-
// span: 8
|
|
152
|
-
// }
|
|
153
|
-
// })
|
|
154
|
-
// }
|
|
155
|
-
// }
|
|
156
|
-
// window.addEventListener('resize', handleResize)
|
|
157
|
-
</script>
|
|
158
|
-
<style scoped lang="scss">
|
|
159
|
-
.search-btn {
|
|
160
|
-
margin-right: 20px;
|
|
161
|
-
margin-left: auto;
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
.c-search {
|
|
165
|
-
position: relative;
|
|
166
|
-
height: 50px;
|
|
167
|
-
|
|
168
|
-
.c-search-simple {
|
|
169
|
-
display: flex;
|
|
170
|
-
justify-content: space-between;
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
.c-search-simple-btn {
|
|
174
|
-
display: flex;
|
|
175
|
-
margin-left: auto;
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
.c-search-simple-icon {
|
|
179
|
-
display: flex;
|
|
180
|
-
justify-content: center;
|
|
181
|
-
align-items: center;
|
|
182
|
-
cursor: pointer;
|
|
183
|
-
height: 32px;
|
|
184
|
-
width: 32px;
|
|
185
|
-
margin-right: 10px;
|
|
186
|
-
border-radius: 4px;
|
|
187
|
-
background-color: #409eff;
|
|
188
|
-
transition: all 0.2s;
|
|
189
|
-
|
|
190
|
-
&:hover {
|
|
191
|
-
background-color: rgb(121, 187, 255);
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
&:active {
|
|
195
|
-
background-color: rgb(51, 126, 204);
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
.c-search-icon {
|
|
200
|
-
// 添加鼠标悬停效果
|
|
201
|
-
display: inline-block;
|
|
202
|
-
color: #fff;
|
|
203
|
-
transition: all 0.2s;
|
|
204
|
-
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
.icon-rotate {
|
|
208
|
-
background-color: rgb(51, 126, 204);
|
|
209
|
-
|
|
210
|
-
.c-search-icon {
|
|
211
|
-
transform: rotate(180deg);
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
.c-search-form {
|
|
216
|
-
width: 100%;
|
|
217
|
-
position: absolute;
|
|
218
|
-
top: 50px;
|
|
219
|
-
left: 0;
|
|
220
|
-
overflow: hidden;
|
|
221
|
-
z-index: 10;
|
|
222
|
-
background-color: #fff;
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
/* 下拉动画效果 */
|
|
227
|
-
.search-form-transition {
|
|
228
|
-
|
|
229
|
-
&-enter-active,
|
|
230
|
-
&-leave-active {
|
|
231
|
-
transition: all 0.3s ease;
|
|
232
|
-
/* 动画过渡时间和缓动函数 */
|
|
233
|
-
overflow: hidden;
|
|
234
|
-
max-height: 500px;
|
|
235
|
-
/* 确保足够大的最大高度以容纳内容 */
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
&-enter-from {
|
|
239
|
-
max-height: 0;
|
|
240
|
-
/* 入场开始时高度为0 */
|
|
241
|
-
opacity: 0;
|
|
242
|
-
/* 可以添加透明度效果增强视觉体验 */
|
|
243
|
-
padding-top: 0;
|
|
244
|
-
padding-bottom: 0;
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
&-leave-to {
|
|
248
|
-
max-height: 0;
|
|
249
|
-
/* 出场结束时高度为0 */
|
|
250
|
-
opacity: 0;
|
|
251
|
-
/* 可以添加透明度效果增强视觉体验 */
|
|
252
|
-
padding-top: 0;
|
|
253
|
-
padding-bottom: 0;
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
</style>
|