@cmstops/pro-compo 0.1.74 → 0.1.75
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/es/baseFilter/component.js +15 -19
- package/es/baseFilter/components/FilterGroup.d.ts +0 -0
- package/es/baseFilter/components/FilterGroup.js +179 -0
- package/es/baseFilter/components/filterItem.js +4 -2
- package/es/baseFilter/style/css.js +1 -0
- package/es/baseFilter/style/filterGroup.less +60 -0
- package/es/baseFilter/style/index.d.ts +1 -0
- package/es/baseFilter/style/index.js +1 -0
- package/es/baseFilter/useCalcWidth.d.ts +9 -0
- package/lib/baseFilter/component.js +12 -16
- package/lib/baseFilter/components/FilterGroup.js +180 -0
- package/lib/baseFilter/components/filterItem.js +3 -1
- package/lib/baseFilter/style/css.js +1 -0
- package/lib/baseFilter/style/filterGroup.less +60 -0
- package/lib/baseFilter/style/index.js +1 -0
- package/package.json +1 -1
|
@@ -1,13 +1,7 @@
|
|
|
1
|
-
import { defineComponent, ref, computed, watch, toRaw, openBlock, createElementBlock,
|
|
1
|
+
import { defineComponent, ref, computed, watch, toRaw, openBlock, createElementBlock, Fragment, createVNode, withCtx, renderList, createBlock, unref, normalizeStyle, createCommentVNode, withModifiers, renderSlot } from "vue";
|
|
2
2
|
import { InputSearch, Select, Option, RangePicker } from "@arco-design/web-vue";
|
|
3
|
-
import _sfc_main$
|
|
4
|
-
|
|
5
|
-
const _hoisted_2 = { class: "left" };
|
|
6
|
-
const _hoisted_3 = {
|
|
7
|
-
key: 0,
|
|
8
|
-
class: "form-ul"
|
|
9
|
-
};
|
|
10
|
-
const _hoisted_4 = { class: "right" };
|
|
3
|
+
import _sfc_main$2 from "./components/filterItem.js";
|
|
4
|
+
import _sfc_main$1 from "./components/FilterGroup.js";
|
|
11
5
|
const _sfc_main = defineComponent({
|
|
12
6
|
...{ name: "baseFilter" },
|
|
13
7
|
__name: "component",
|
|
@@ -130,11 +124,11 @@ const _sfc_main = defineComponent({
|
|
|
130
124
|
{ deep: true }
|
|
131
125
|
);
|
|
132
126
|
return (_ctx, _cache) => {
|
|
133
|
-
return openBlock(), createElementBlock(
|
|
134
|
-
|
|
135
|
-
|
|
127
|
+
return openBlock(), createElementBlock(Fragment, null, [
|
|
128
|
+
createVNode(_sfc_main$1, null, {
|
|
129
|
+
left: withCtx(() => [
|
|
136
130
|
(openBlock(true), createElementBlock(Fragment, null, renderList(renderColumns.value, (item, index) => {
|
|
137
|
-
return openBlock(), createBlock(_sfc_main$
|
|
131
|
+
return openBlock(), createBlock(_sfc_main$2, {
|
|
138
132
|
key: index,
|
|
139
133
|
active: hasValue.value(item.key)
|
|
140
134
|
}, {
|
|
@@ -180,12 +174,14 @@ const _sfc_main = defineComponent({
|
|
|
180
174
|
_: 2
|
|
181
175
|
}, 1032, ["active"]);
|
|
182
176
|
}), 128))
|
|
183
|
-
])
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
177
|
+
]),
|
|
178
|
+
right: withCtx(() => [
|
|
179
|
+
renderSlot(_ctx.$slots, "right")
|
|
180
|
+
]),
|
|
181
|
+
_: 3
|
|
182
|
+
}),
|
|
183
|
+
createCommentVNode(' <div class="base-filter-container">\n <div class="left">\n <div v-if="render" class="form-ul">\n <template v-for="(item, index) in renderColumns" :key="index">\n <filter-item :active="hasValue(item.key)">\n <a-input-search\n v-if="item.component === \'input\'"\n v-model="form[item.key]"\n :style="{ width: styleWidth(columnsMap[item.key]) }"\n allow-clear\n size="medium"\n :placeholder="`\u8BF7\u8F93\u5165${item.label}`"\n />\n <a-select\n v-if="item.component === \'select\'"\n v-model="form[item.key]"\n allow-clear\n :style="{ width: styleWidth(columnsMap[item.key]) }"\n :placeholder="`\u8BF7\u9009\u62E9${item.label}`"\n >\n <template v-for="opt in getOptions(item)" :key="opt.value">\n <a-option :label="opt.label" :value="opt.value"></a-option\n ></template>\n </a-select>\n <a-range-picker\n v-if="item.component === \'range-picker\'"\n v-model="form[item.key].range"\n :style="{ width: styleWidth(form[item.key]) }"\n value-format="timestamp"\n @click.stop\n />\n </filter-item>\n </template>\n </div>\n </div>\n <div class="right">\n <slot name="right"></slot>\n </div>\n </div> ')
|
|
184
|
+
], 2112);
|
|
189
185
|
};
|
|
190
186
|
}
|
|
191
187
|
});
|
|
File without changes
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
import { defineComponent, ref, watch, onMounted, openBlock, createElementBlock, createElementVNode, withDirectives, createVNode, unref, withModifiers, withCtx, createTextVNode, vShow, renderSlot } from "vue";
|
|
2
|
+
import { Button } from "@arco-design/web-vue";
|
|
3
|
+
import { IconCaretDown } from "@arco-design/web-vue/es/icon";
|
|
4
|
+
import { createPopper } from "@popperjs/core";
|
|
5
|
+
const _hoisted_1 = { class: "filter-view-container" };
|
|
6
|
+
const _hoisted_2 = { class: "more-btn" };
|
|
7
|
+
const _hoisted_3 = { class: "right-prefix" };
|
|
8
|
+
const _hoisted_4 = { class: "filter-content" };
|
|
9
|
+
const _hoisted_5 = { class: "right" };
|
|
10
|
+
const _hoisted_6 = {
|
|
11
|
+
ref: "tempNode",
|
|
12
|
+
style: { "display": "none" }
|
|
13
|
+
};
|
|
14
|
+
const _sfc_main = defineComponent({
|
|
15
|
+
__name: "FilterGroup",
|
|
16
|
+
setup(__props) {
|
|
17
|
+
const documentWidth = ref(0);
|
|
18
|
+
const overflowWidth = ref(0);
|
|
19
|
+
watch(
|
|
20
|
+
() => documentWidth.value,
|
|
21
|
+
(n) => checkOverflow()
|
|
22
|
+
);
|
|
23
|
+
watch(
|
|
24
|
+
() => overflowWidth.value,
|
|
25
|
+
(n) => setPannelItem()
|
|
26
|
+
);
|
|
27
|
+
const initDocWidthListener = function() {
|
|
28
|
+
window.onresize = (() => {
|
|
29
|
+
return () => {
|
|
30
|
+
documentWidth.value = document.body.clientWidth;
|
|
31
|
+
};
|
|
32
|
+
})();
|
|
33
|
+
};
|
|
34
|
+
const filterItemsRef = ref();
|
|
35
|
+
const moreBtnRef = ref();
|
|
36
|
+
const dpPannelRef = ref();
|
|
37
|
+
const initPopper = function() {
|
|
38
|
+
createPopper(moreBtnRef.value, dpPannelRef.value, {
|
|
39
|
+
placement: "bottom-start"
|
|
40
|
+
});
|
|
41
|
+
};
|
|
42
|
+
const popperShowFlag = ref(false);
|
|
43
|
+
function showPopper() {
|
|
44
|
+
popperShowFlag.value = true;
|
|
45
|
+
window.onclick = hidePopper;
|
|
46
|
+
}
|
|
47
|
+
function hidePopper() {
|
|
48
|
+
popperShowFlag.value = false;
|
|
49
|
+
}
|
|
50
|
+
const itemNodeArr = ref([]);
|
|
51
|
+
const itemWidthArr = ref([]);
|
|
52
|
+
const itemArr = ref([]);
|
|
53
|
+
function checkOverflow() {
|
|
54
|
+
if (!filterItemsRef.value)
|
|
55
|
+
return;
|
|
56
|
+
const parent = filterItemsRef.value.parentNode;
|
|
57
|
+
if (!itemNodeArr.value.length) {
|
|
58
|
+
itemNodeArr.value = mapNodes(filterItemsRef.value.childNodes);
|
|
59
|
+
itemWidthArr.value = itemNodeArr.value.map((node) => node.clientWidth + 10);
|
|
60
|
+
itemArr.value = itemWidthArr.value.map((_, idx) => idx);
|
|
61
|
+
}
|
|
62
|
+
const parentWidth = parent.clientWidth;
|
|
63
|
+
const leftWidth = getArrWidth(itemWidthArr.value);
|
|
64
|
+
const rightWidth = parent.childNodes[parent.childNodes.length - 1].clientWidth;
|
|
65
|
+
overflowWidth.value = leftWidth + rightWidth - parentWidth;
|
|
66
|
+
}
|
|
67
|
+
function mapNodes(nodes) {
|
|
68
|
+
const nodeArr = [];
|
|
69
|
+
for (let i = 0; i < nodes.length; i++) {
|
|
70
|
+
const element = nodes[i];
|
|
71
|
+
nodeArr.push(element);
|
|
72
|
+
}
|
|
73
|
+
return nodeArr.filter((item) => item.clientWidth);
|
|
74
|
+
}
|
|
75
|
+
function getArrWidth(arr) {
|
|
76
|
+
return arr.reduce((prev, cur) => prev + cur, 0);
|
|
77
|
+
}
|
|
78
|
+
const pannelArray = ref("");
|
|
79
|
+
watch(
|
|
80
|
+
() => pannelArray.value,
|
|
81
|
+
(n, o) => refreshPannel(n, o)
|
|
82
|
+
);
|
|
83
|
+
function refreshPannel(newStr, oldStr) {
|
|
84
|
+
const nArr = newStr ? newStr.split(",") : [];
|
|
85
|
+
const oArr = oldStr ? oldStr.split(",") : [];
|
|
86
|
+
if (nArr.length && nArr.length > oArr.length) {
|
|
87
|
+
diff(nArr, oArr).forEach((index) => inNode(parseInt(index, 10)));
|
|
88
|
+
} else if (nArr.length >= 0 && nArr.length < oArr.length) {
|
|
89
|
+
diff(oArr, nArr).forEach((index) => outNode(parseInt(index, 10)));
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
const diff = (arr1, arr2) => {
|
|
93
|
+
const diff2 = [];
|
|
94
|
+
for (let i = 0; i < arr1.length; i++) {
|
|
95
|
+
const item = arr1[i];
|
|
96
|
+
if (!arr2.includes(item))
|
|
97
|
+
diff2.push(item);
|
|
98
|
+
}
|
|
99
|
+
return diff2;
|
|
100
|
+
};
|
|
101
|
+
function inNode(index) {
|
|
102
|
+
var _a, _b, _c;
|
|
103
|
+
const node = mapNodes((_a = filterItemsRef.value) == null ? void 0 : _a.childNodes)[index];
|
|
104
|
+
const temp = document.createElement("div");
|
|
105
|
+
temp.style.width = `${itemWidthArr.value[index]}px`;
|
|
106
|
+
temp.style.position = "absolute";
|
|
107
|
+
temp.style.left = `${50}px`;
|
|
108
|
+
(_b = filterItemsRef.value) == null ? void 0 : _b.replaceChild(temp, node);
|
|
109
|
+
(_c = dpPannelRef.value) == null ? void 0 : _c.appendChild(node);
|
|
110
|
+
}
|
|
111
|
+
function outNode(index) {
|
|
112
|
+
var _a;
|
|
113
|
+
const node = itemNodeArr.value[index];
|
|
114
|
+
(_a = filterItemsRef.value) == null ? void 0 : _a.replaceChild(
|
|
115
|
+
node,
|
|
116
|
+
mapNodes(filterItemsRef.value.childNodes)[index]
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
function setPannelItem() {
|
|
120
|
+
let inPannelNum = 0;
|
|
121
|
+
if (overflowWidth.value > 0) {
|
|
122
|
+
const avgWidth = 120;
|
|
123
|
+
inPannelNum = Math.ceil((overflowWidth.value + 200) / avgWidth);
|
|
124
|
+
}
|
|
125
|
+
pannelArray.value = itemArr.value.slice(0, inPannelNum).join(",");
|
|
126
|
+
}
|
|
127
|
+
onMounted(() => {
|
|
128
|
+
initDocWidthListener();
|
|
129
|
+
initPopper();
|
|
130
|
+
setTimeout(() => checkOverflow());
|
|
131
|
+
});
|
|
132
|
+
return (_ctx, _cache) => {
|
|
133
|
+
return openBlock(), createElementBlock("div", _hoisted_1, [
|
|
134
|
+
createElementVNode("div", _hoisted_2, [
|
|
135
|
+
createElementVNode("div", {
|
|
136
|
+
ref_key: "moreBtnRef",
|
|
137
|
+
ref: moreBtnRef
|
|
138
|
+
}, [
|
|
139
|
+
withDirectives(createVNode(unref(Button), {
|
|
140
|
+
onClick: withModifiers(showPopper, ["stop"])
|
|
141
|
+
}, {
|
|
142
|
+
default: withCtx(() => [
|
|
143
|
+
createElementVNode("span", _hoisted_3, [
|
|
144
|
+
createTextVNode(" \u66F4\u591A\u7B5B\u9009 "),
|
|
145
|
+
createVNode(unref(IconCaretDown))
|
|
146
|
+
])
|
|
147
|
+
]),
|
|
148
|
+
_: 1
|
|
149
|
+
}, 512), [
|
|
150
|
+
[vShow, pannelArray.value]
|
|
151
|
+
])
|
|
152
|
+
], 512),
|
|
153
|
+
withDirectives(createElementVNode("div", {
|
|
154
|
+
id: "dpPannelRef",
|
|
155
|
+
ref_key: "dpPannelRef",
|
|
156
|
+
ref: dpPannelRef,
|
|
157
|
+
class: "filter-pannel"
|
|
158
|
+
}, null, 512), [
|
|
159
|
+
[vShow, popperShowFlag.value]
|
|
160
|
+
])
|
|
161
|
+
]),
|
|
162
|
+
createElementVNode("div", _hoisted_4, [
|
|
163
|
+
createElementVNode("div", {
|
|
164
|
+
ref_key: "filterItemsRef",
|
|
165
|
+
ref: filterItemsRef,
|
|
166
|
+
class: "left"
|
|
167
|
+
}, [
|
|
168
|
+
renderSlot(_ctx.$slots, "left")
|
|
169
|
+
], 512),
|
|
170
|
+
createElementVNode("div", _hoisted_5, [
|
|
171
|
+
renderSlot(_ctx.$slots, "right")
|
|
172
|
+
])
|
|
173
|
+
]),
|
|
174
|
+
createElementVNode("div", _hoisted_6, null, 512)
|
|
175
|
+
]);
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
});
|
|
179
|
+
export { _sfc_main as default };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { defineComponent, openBlock, createElementBlock, normalizeClass, renderSlot } from "vue";
|
|
1
|
+
import { defineComponent, openBlock, createElementBlock, normalizeClass, withModifiers, renderSlot } from "vue";
|
|
2
2
|
const _sfc_main = defineComponent({
|
|
3
3
|
...{ name: "filter-item-view" },
|
|
4
4
|
__name: "filterItem",
|
|
@@ -8,7 +8,9 @@ const _sfc_main = defineComponent({
|
|
|
8
8
|
setup(__props) {
|
|
9
9
|
return (_ctx, _cache) => {
|
|
10
10
|
return openBlock(), createElementBlock("div", {
|
|
11
|
-
class: normalizeClass(["filter-item-view", { value: _ctx.active }])
|
|
11
|
+
class: normalizeClass(["filter-item-view", { value: _ctx.active }]),
|
|
12
|
+
onClick: _cache[0] || (_cache[0] = withModifiers(() => {
|
|
13
|
+
}, ["stop"]))
|
|
12
14
|
}, [
|
|
13
15
|
renderSlot(_ctx.$slots, "default")
|
|
14
16
|
], 2);
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
// FilterGroup 内部样式
|
|
2
|
+
.filter-view-container {
|
|
3
|
+
display: flex;
|
|
4
|
+
align-items: center;
|
|
5
|
+
margin-bottom: 10px;
|
|
6
|
+
font-size: 14px;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.filter-search {
|
|
10
|
+
display: flex;
|
|
11
|
+
gap: 10px;
|
|
12
|
+
width: 180px;
|
|
13
|
+
margin-right: 10px;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
.filter-content {
|
|
17
|
+
position: relative;
|
|
18
|
+
display: flex;
|
|
19
|
+
flex: 1;
|
|
20
|
+
align-items: center;
|
|
21
|
+
justify-content: space-between;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.left {
|
|
25
|
+
display: flex;
|
|
26
|
+
gap: 10px;
|
|
27
|
+
align-items: center;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.right {
|
|
31
|
+
position: absolute;
|
|
32
|
+
right: 0;
|
|
33
|
+
z-index: 1;
|
|
34
|
+
display: flex;
|
|
35
|
+
flex-wrap: nowrap;
|
|
36
|
+
align-items: center;
|
|
37
|
+
height: 100%;
|
|
38
|
+
padding-left: 20px;
|
|
39
|
+
background: white;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.more-btn {
|
|
43
|
+
z-index: 10;
|
|
44
|
+
margin-right: 10px;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.right-prefix {
|
|
48
|
+
display: flex;
|
|
49
|
+
gap: 10px;
|
|
50
|
+
align-items: center;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.filter-pannel {
|
|
54
|
+
display: flex;
|
|
55
|
+
gap: 10px;
|
|
56
|
+
padding: 10px;
|
|
57
|
+
background-color: white;
|
|
58
|
+
border-radius: 6px;
|
|
59
|
+
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
|
|
60
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Ref } from 'vue';
|
|
2
|
+
export default function useCalcWidth(filterItemsRef: Ref<HTMLElement | undefined>, dpPannelRef: Ref<HTMLElement | undefined>, moreBtnRef: Ref<HTMLElement | undefined>): {
|
|
3
|
+
pannelArray: Ref<string>;
|
|
4
|
+
popperShowFlag: Ref<boolean>;
|
|
5
|
+
showPopper: () => void;
|
|
6
|
+
initDocWidthListener: () => void;
|
|
7
|
+
initPopper: () => void;
|
|
8
|
+
checkOverflow: () => void;
|
|
9
|
+
};
|
|
@@ -2,13 +2,7 @@
|
|
|
2
2
|
var vue = require("vue");
|
|
3
3
|
var webVue = require("@arco-design/web-vue");
|
|
4
4
|
var filterItem = require("./components/filterItem.js");
|
|
5
|
-
|
|
6
|
-
const _hoisted_2 = { class: "left" };
|
|
7
|
-
const _hoisted_3 = {
|
|
8
|
-
key: 0,
|
|
9
|
-
class: "form-ul"
|
|
10
|
-
};
|
|
11
|
-
const _hoisted_4 = { class: "right" };
|
|
5
|
+
var FilterGroup = require("./components/FilterGroup.js");
|
|
12
6
|
const _sfc_main = vue.defineComponent({
|
|
13
7
|
...{ name: "baseFilter" },
|
|
14
8
|
__name: "component",
|
|
@@ -131,9 +125,9 @@ const _sfc_main = vue.defineComponent({
|
|
|
131
125
|
{ deep: true }
|
|
132
126
|
);
|
|
133
127
|
return (_ctx, _cache) => {
|
|
134
|
-
return vue.openBlock(), vue.createElementBlock(
|
|
135
|
-
vue.
|
|
136
|
-
|
|
128
|
+
return vue.openBlock(), vue.createElementBlock(vue.Fragment, null, [
|
|
129
|
+
vue.createVNode(FilterGroup, null, {
|
|
130
|
+
left: vue.withCtx(() => [
|
|
137
131
|
(vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(renderColumns.value, (item, index) => {
|
|
138
132
|
return vue.openBlock(), vue.createBlock(filterItem, {
|
|
139
133
|
key: index,
|
|
@@ -181,12 +175,14 @@ const _sfc_main = vue.defineComponent({
|
|
|
181
175
|
_: 2
|
|
182
176
|
}, 1032, ["active"]);
|
|
183
177
|
}), 128))
|
|
184
|
-
])
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
178
|
+
]),
|
|
179
|
+
right: vue.withCtx(() => [
|
|
180
|
+
vue.renderSlot(_ctx.$slots, "right")
|
|
181
|
+
]),
|
|
182
|
+
_: 3
|
|
183
|
+
}),
|
|
184
|
+
vue.createCommentVNode(' <div class="base-filter-container">\n <div class="left">\n <div v-if="render" class="form-ul">\n <template v-for="(item, index) in renderColumns" :key="index">\n <filter-item :active="hasValue(item.key)">\n <a-input-search\n v-if="item.component === \'input\'"\n v-model="form[item.key]"\n :style="{ width: styleWidth(columnsMap[item.key]) }"\n allow-clear\n size="medium"\n :placeholder="`\u8BF7\u8F93\u5165${item.label}`"\n />\n <a-select\n v-if="item.component === \'select\'"\n v-model="form[item.key]"\n allow-clear\n :style="{ width: styleWidth(columnsMap[item.key]) }"\n :placeholder="`\u8BF7\u9009\u62E9${item.label}`"\n >\n <template v-for="opt in getOptions(item)" :key="opt.value">\n <a-option :label="opt.label" :value="opt.value"></a-option\n ></template>\n </a-select>\n <a-range-picker\n v-if="item.component === \'range-picker\'"\n v-model="form[item.key].range"\n :style="{ width: styleWidth(form[item.key]) }"\n value-format="timestamp"\n @click.stop\n />\n </filter-item>\n </template>\n </div>\n </div>\n <div class="right">\n <slot name="right"></slot>\n </div>\n </div> ')
|
|
185
|
+
], 2112);
|
|
190
186
|
};
|
|
191
187
|
}
|
|
192
188
|
});
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var vue = require("vue");
|
|
3
|
+
var webVue = require("@arco-design/web-vue");
|
|
4
|
+
var icon = require("@arco-design/web-vue/es/icon");
|
|
5
|
+
var core = require("@popperjs/core");
|
|
6
|
+
const _hoisted_1 = { class: "filter-view-container" };
|
|
7
|
+
const _hoisted_2 = { class: "more-btn" };
|
|
8
|
+
const _hoisted_3 = { class: "right-prefix" };
|
|
9
|
+
const _hoisted_4 = { class: "filter-content" };
|
|
10
|
+
const _hoisted_5 = { class: "right" };
|
|
11
|
+
const _hoisted_6 = {
|
|
12
|
+
ref: "tempNode",
|
|
13
|
+
style: { "display": "none" }
|
|
14
|
+
};
|
|
15
|
+
const _sfc_main = vue.defineComponent({
|
|
16
|
+
__name: "FilterGroup",
|
|
17
|
+
setup(__props) {
|
|
18
|
+
const documentWidth = vue.ref(0);
|
|
19
|
+
const overflowWidth = vue.ref(0);
|
|
20
|
+
vue.watch(
|
|
21
|
+
() => documentWidth.value,
|
|
22
|
+
(n) => checkOverflow()
|
|
23
|
+
);
|
|
24
|
+
vue.watch(
|
|
25
|
+
() => overflowWidth.value,
|
|
26
|
+
(n) => setPannelItem()
|
|
27
|
+
);
|
|
28
|
+
const initDocWidthListener = function() {
|
|
29
|
+
window.onresize = (() => {
|
|
30
|
+
return () => {
|
|
31
|
+
documentWidth.value = document.body.clientWidth;
|
|
32
|
+
};
|
|
33
|
+
})();
|
|
34
|
+
};
|
|
35
|
+
const filterItemsRef = vue.ref();
|
|
36
|
+
const moreBtnRef = vue.ref();
|
|
37
|
+
const dpPannelRef = vue.ref();
|
|
38
|
+
const initPopper = function() {
|
|
39
|
+
core.createPopper(moreBtnRef.value, dpPannelRef.value, {
|
|
40
|
+
placement: "bottom-start"
|
|
41
|
+
});
|
|
42
|
+
};
|
|
43
|
+
const popperShowFlag = vue.ref(false);
|
|
44
|
+
function showPopper() {
|
|
45
|
+
popperShowFlag.value = true;
|
|
46
|
+
window.onclick = hidePopper;
|
|
47
|
+
}
|
|
48
|
+
function hidePopper() {
|
|
49
|
+
popperShowFlag.value = false;
|
|
50
|
+
}
|
|
51
|
+
const itemNodeArr = vue.ref([]);
|
|
52
|
+
const itemWidthArr = vue.ref([]);
|
|
53
|
+
const itemArr = vue.ref([]);
|
|
54
|
+
function checkOverflow() {
|
|
55
|
+
if (!filterItemsRef.value)
|
|
56
|
+
return;
|
|
57
|
+
const parent = filterItemsRef.value.parentNode;
|
|
58
|
+
if (!itemNodeArr.value.length) {
|
|
59
|
+
itemNodeArr.value = mapNodes(filterItemsRef.value.childNodes);
|
|
60
|
+
itemWidthArr.value = itemNodeArr.value.map((node) => node.clientWidth + 10);
|
|
61
|
+
itemArr.value = itemWidthArr.value.map((_, idx) => idx);
|
|
62
|
+
}
|
|
63
|
+
const parentWidth = parent.clientWidth;
|
|
64
|
+
const leftWidth = getArrWidth(itemWidthArr.value);
|
|
65
|
+
const rightWidth = parent.childNodes[parent.childNodes.length - 1].clientWidth;
|
|
66
|
+
overflowWidth.value = leftWidth + rightWidth - parentWidth;
|
|
67
|
+
}
|
|
68
|
+
function mapNodes(nodes) {
|
|
69
|
+
const nodeArr = [];
|
|
70
|
+
for (let i = 0; i < nodes.length; i++) {
|
|
71
|
+
const element = nodes[i];
|
|
72
|
+
nodeArr.push(element);
|
|
73
|
+
}
|
|
74
|
+
return nodeArr.filter((item) => item.clientWidth);
|
|
75
|
+
}
|
|
76
|
+
function getArrWidth(arr) {
|
|
77
|
+
return arr.reduce((prev, cur) => prev + cur, 0);
|
|
78
|
+
}
|
|
79
|
+
const pannelArray = vue.ref("");
|
|
80
|
+
vue.watch(
|
|
81
|
+
() => pannelArray.value,
|
|
82
|
+
(n, o) => refreshPannel(n, o)
|
|
83
|
+
);
|
|
84
|
+
function refreshPannel(newStr, oldStr) {
|
|
85
|
+
const nArr = newStr ? newStr.split(",") : [];
|
|
86
|
+
const oArr = oldStr ? oldStr.split(",") : [];
|
|
87
|
+
if (nArr.length && nArr.length > oArr.length) {
|
|
88
|
+
diff(nArr, oArr).forEach((index) => inNode(parseInt(index, 10)));
|
|
89
|
+
} else if (nArr.length >= 0 && nArr.length < oArr.length) {
|
|
90
|
+
diff(oArr, nArr).forEach((index) => outNode(parseInt(index, 10)));
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
const diff = (arr1, arr2) => {
|
|
94
|
+
const diff2 = [];
|
|
95
|
+
for (let i = 0; i < arr1.length; i++) {
|
|
96
|
+
const item = arr1[i];
|
|
97
|
+
if (!arr2.includes(item))
|
|
98
|
+
diff2.push(item);
|
|
99
|
+
}
|
|
100
|
+
return diff2;
|
|
101
|
+
};
|
|
102
|
+
function inNode(index) {
|
|
103
|
+
var _a, _b, _c;
|
|
104
|
+
const node = mapNodes((_a = filterItemsRef.value) == null ? void 0 : _a.childNodes)[index];
|
|
105
|
+
const temp = document.createElement("div");
|
|
106
|
+
temp.style.width = `${itemWidthArr.value[index]}px`;
|
|
107
|
+
temp.style.position = "absolute";
|
|
108
|
+
temp.style.left = `${50}px`;
|
|
109
|
+
(_b = filterItemsRef.value) == null ? void 0 : _b.replaceChild(temp, node);
|
|
110
|
+
(_c = dpPannelRef.value) == null ? void 0 : _c.appendChild(node);
|
|
111
|
+
}
|
|
112
|
+
function outNode(index) {
|
|
113
|
+
var _a;
|
|
114
|
+
const node = itemNodeArr.value[index];
|
|
115
|
+
(_a = filterItemsRef.value) == null ? void 0 : _a.replaceChild(
|
|
116
|
+
node,
|
|
117
|
+
mapNodes(filterItemsRef.value.childNodes)[index]
|
|
118
|
+
);
|
|
119
|
+
}
|
|
120
|
+
function setPannelItem() {
|
|
121
|
+
let inPannelNum = 0;
|
|
122
|
+
if (overflowWidth.value > 0) {
|
|
123
|
+
const avgWidth = 120;
|
|
124
|
+
inPannelNum = Math.ceil((overflowWidth.value + 200) / avgWidth);
|
|
125
|
+
}
|
|
126
|
+
pannelArray.value = itemArr.value.slice(0, inPannelNum).join(",");
|
|
127
|
+
}
|
|
128
|
+
vue.onMounted(() => {
|
|
129
|
+
initDocWidthListener();
|
|
130
|
+
initPopper();
|
|
131
|
+
setTimeout(() => checkOverflow());
|
|
132
|
+
});
|
|
133
|
+
return (_ctx, _cache) => {
|
|
134
|
+
return vue.openBlock(), vue.createElementBlock("div", _hoisted_1, [
|
|
135
|
+
vue.createElementVNode("div", _hoisted_2, [
|
|
136
|
+
vue.createElementVNode("div", {
|
|
137
|
+
ref_key: "moreBtnRef",
|
|
138
|
+
ref: moreBtnRef
|
|
139
|
+
}, [
|
|
140
|
+
vue.withDirectives(vue.createVNode(vue.unref(webVue.Button), {
|
|
141
|
+
onClick: vue.withModifiers(showPopper, ["stop"])
|
|
142
|
+
}, {
|
|
143
|
+
default: vue.withCtx(() => [
|
|
144
|
+
vue.createElementVNode("span", _hoisted_3, [
|
|
145
|
+
vue.createTextVNode(" \u66F4\u591A\u7B5B\u9009 "),
|
|
146
|
+
vue.createVNode(vue.unref(icon.IconCaretDown))
|
|
147
|
+
])
|
|
148
|
+
]),
|
|
149
|
+
_: 1
|
|
150
|
+
}, 512), [
|
|
151
|
+
[vue.vShow, pannelArray.value]
|
|
152
|
+
])
|
|
153
|
+
], 512),
|
|
154
|
+
vue.withDirectives(vue.createElementVNode("div", {
|
|
155
|
+
id: "dpPannelRef",
|
|
156
|
+
ref_key: "dpPannelRef",
|
|
157
|
+
ref: dpPannelRef,
|
|
158
|
+
class: "filter-pannel"
|
|
159
|
+
}, null, 512), [
|
|
160
|
+
[vue.vShow, popperShowFlag.value]
|
|
161
|
+
])
|
|
162
|
+
]),
|
|
163
|
+
vue.createElementVNode("div", _hoisted_4, [
|
|
164
|
+
vue.createElementVNode("div", {
|
|
165
|
+
ref_key: "filterItemsRef",
|
|
166
|
+
ref: filterItemsRef,
|
|
167
|
+
class: "left"
|
|
168
|
+
}, [
|
|
169
|
+
vue.renderSlot(_ctx.$slots, "left")
|
|
170
|
+
], 512),
|
|
171
|
+
vue.createElementVNode("div", _hoisted_5, [
|
|
172
|
+
vue.renderSlot(_ctx.$slots, "right")
|
|
173
|
+
])
|
|
174
|
+
]),
|
|
175
|
+
vue.createElementVNode("div", _hoisted_6, null, 512)
|
|
176
|
+
]);
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
});
|
|
180
|
+
module.exports = _sfc_main;
|
|
@@ -9,7 +9,9 @@ const _sfc_main = vue.defineComponent({
|
|
|
9
9
|
setup(__props) {
|
|
10
10
|
return (_ctx, _cache) => {
|
|
11
11
|
return vue.openBlock(), vue.createElementBlock("div", {
|
|
12
|
-
class: vue.normalizeClass(["filter-item-view", { value: _ctx.active }])
|
|
12
|
+
class: vue.normalizeClass(["filter-item-view", { value: _ctx.active }]),
|
|
13
|
+
onClick: _cache[0] || (_cache[0] = vue.withModifiers(() => {
|
|
14
|
+
}, ["stop"]))
|
|
13
15
|
}, [
|
|
14
16
|
vue.renderSlot(_ctx.$slots, "default")
|
|
15
17
|
], 2);
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
// FilterGroup 内部样式
|
|
2
|
+
.filter-view-container {
|
|
3
|
+
display: flex;
|
|
4
|
+
align-items: center;
|
|
5
|
+
margin-bottom: 10px;
|
|
6
|
+
font-size: 14px;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.filter-search {
|
|
10
|
+
display: flex;
|
|
11
|
+
gap: 10px;
|
|
12
|
+
width: 180px;
|
|
13
|
+
margin-right: 10px;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
.filter-content {
|
|
17
|
+
position: relative;
|
|
18
|
+
display: flex;
|
|
19
|
+
flex: 1;
|
|
20
|
+
align-items: center;
|
|
21
|
+
justify-content: space-between;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.left {
|
|
25
|
+
display: flex;
|
|
26
|
+
gap: 10px;
|
|
27
|
+
align-items: center;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.right {
|
|
31
|
+
position: absolute;
|
|
32
|
+
right: 0;
|
|
33
|
+
z-index: 1;
|
|
34
|
+
display: flex;
|
|
35
|
+
flex-wrap: nowrap;
|
|
36
|
+
align-items: center;
|
|
37
|
+
height: 100%;
|
|
38
|
+
padding-left: 20px;
|
|
39
|
+
background: white;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.more-btn {
|
|
43
|
+
z-index: 10;
|
|
44
|
+
margin-right: 10px;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.right-prefix {
|
|
48
|
+
display: flex;
|
|
49
|
+
gap: 10px;
|
|
50
|
+
align-items: center;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.filter-pannel {
|
|
54
|
+
display: flex;
|
|
55
|
+
gap: 10px;
|
|
56
|
+
padding: 10px;
|
|
57
|
+
background-color: white;
|
|
58
|
+
border-radius: 6px;
|
|
59
|
+
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
|
|
60
|
+
}
|