t20-common-lib 0.12.23 → 0.13.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/package.json
CHANGED
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<el-select
|
|
3
|
+
v-model="innerValue"
|
|
4
|
+
v-select-lazy="lazyGet"
|
|
5
|
+
:multiple="multiple"
|
|
6
|
+
filterable
|
|
7
|
+
clearable
|
|
8
|
+
:filter-method="debouncedFilter"
|
|
9
|
+
:placeholder="placeholder"
|
|
10
|
+
@change="handleChange"
|
|
11
|
+
@focus="handleFocus"
|
|
12
|
+
@clear="() => handleFilter('')"
|
|
13
|
+
>
|
|
14
|
+
<el-option
|
|
15
|
+
v-if="displayOption"
|
|
16
|
+
:key="`display-${displayOption[valueKey]}`"
|
|
17
|
+
:label="displayOption[labelKey]"
|
|
18
|
+
:value="displayOption[valueKey]"
|
|
19
|
+
/>
|
|
20
|
+
|
|
21
|
+
<el-option
|
|
22
|
+
v-for="item in options"
|
|
23
|
+
:key="String(item[valueKey])"
|
|
24
|
+
:label="item[labelKey]"
|
|
25
|
+
:value="item[valueKey]"
|
|
26
|
+
/>
|
|
27
|
+
</el-select>
|
|
28
|
+
</template>
|
|
29
|
+
|
|
30
|
+
<script>
|
|
31
|
+
import { debounce } from 'lodash-es';
|
|
32
|
+
|
|
33
|
+
export default {
|
|
34
|
+
name: "ScrollLoadSelect",
|
|
35
|
+
directives: {
|
|
36
|
+
'select-lazy': {
|
|
37
|
+
bind(el, binding) {
|
|
38
|
+
const dropdown = el.querySelector('.el-select-dropdown__wrap');
|
|
39
|
+
if (!dropdown) return;
|
|
40
|
+
|
|
41
|
+
let maxMoveY = 0;
|
|
42
|
+
dropdown.addEventListener('scroll', function () {
|
|
43
|
+
if (this.scrollTop <= 20) {
|
|
44
|
+
maxMoveY = 0;
|
|
45
|
+
}
|
|
46
|
+
if (this.scrollTop > maxMoveY + 60 && this.scrollTop + this.clientHeight > this.scrollHeight - 60) {
|
|
47
|
+
maxMoveY = this.scrollTop;
|
|
48
|
+
if (typeof binding.value === 'function') binding.value();
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
props: {
|
|
55
|
+
value: {
|
|
56
|
+
type: [String, Number, Array, Object],
|
|
57
|
+
default: undefined
|
|
58
|
+
},
|
|
59
|
+
multiple: {
|
|
60
|
+
type: Boolean,
|
|
61
|
+
default: false,
|
|
62
|
+
},
|
|
63
|
+
requestFn: {
|
|
64
|
+
type: Function,
|
|
65
|
+
required: true
|
|
66
|
+
},
|
|
67
|
+
labelKey: {
|
|
68
|
+
type: String,
|
|
69
|
+
default: "label",
|
|
70
|
+
},
|
|
71
|
+
valueKey: {
|
|
72
|
+
type: String,
|
|
73
|
+
default: "value",
|
|
74
|
+
},
|
|
75
|
+
placeholder: {
|
|
76
|
+
type: String,
|
|
77
|
+
default: "",
|
|
78
|
+
},
|
|
79
|
+
pageSize: {
|
|
80
|
+
type: Number,
|
|
81
|
+
default: 20,
|
|
82
|
+
},
|
|
83
|
+
searchKeyName: {
|
|
84
|
+
type: String,
|
|
85
|
+
default: "searchKey",
|
|
86
|
+
},
|
|
87
|
+
selectedLabel: {
|
|
88
|
+
type: String,
|
|
89
|
+
default: "",
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
data() {
|
|
93
|
+
return {
|
|
94
|
+
innerValue: this.value,
|
|
95
|
+
options: [],
|
|
96
|
+
page: {
|
|
97
|
+
current: 1,
|
|
98
|
+
size: this.pageSize,
|
|
99
|
+
key: "",
|
|
100
|
+
hasMore: true,
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
},
|
|
104
|
+
watch: {
|
|
105
|
+
value(newVal) {
|
|
106
|
+
this.innerValue = newVal;
|
|
107
|
+
},
|
|
108
|
+
pageSize(newVal) {
|
|
109
|
+
this.page.size = newVal;
|
|
110
|
+
}
|
|
111
|
+
},
|
|
112
|
+
created() {
|
|
113
|
+
this.debouncedFilter = debounce(this.handleFilter, 300);
|
|
114
|
+
},
|
|
115
|
+
computed: {
|
|
116
|
+
displayOption() {
|
|
117
|
+
if (this.multiple) return null;
|
|
118
|
+
if (this.innerValue === undefined || this.innerValue === null || this.innerValue === "") return null;
|
|
119
|
+
if (!this.selectedLabel) return null;
|
|
120
|
+
|
|
121
|
+
const existed = this.options.some(item => item && item[this.valueKey] == this.innerValue);
|
|
122
|
+
if (existed) return null;
|
|
123
|
+
|
|
124
|
+
return {
|
|
125
|
+
[this.valueKey]: this.innerValue,
|
|
126
|
+
[this.labelKey]: this.selectedLabel,
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
},
|
|
130
|
+
methods: {
|
|
131
|
+
lazyGet() {
|
|
132
|
+
if (this.page.hasMore) {
|
|
133
|
+
this.page.current++;
|
|
134
|
+
this.fetchData(false);
|
|
135
|
+
}
|
|
136
|
+
},
|
|
137
|
+
async fetchData(isInitial = false) {
|
|
138
|
+
if (!this.page.hasMore) return;
|
|
139
|
+
if (typeof this.requestFn !== 'function') return;
|
|
140
|
+
|
|
141
|
+
const params = {
|
|
142
|
+
size: this.page.size,
|
|
143
|
+
current: this.page.current
|
|
144
|
+
};
|
|
145
|
+
params[this.searchKeyName] = this.page.key;
|
|
146
|
+
|
|
147
|
+
try {
|
|
148
|
+
const res = await this.requestFn(params);
|
|
149
|
+
|
|
150
|
+
let data = [];
|
|
151
|
+
if (Array.isArray(res)) {
|
|
152
|
+
data = res;
|
|
153
|
+
} else if (res && Array.isArray(res.list)) {
|
|
154
|
+
data = res.list;
|
|
155
|
+
} else if (res && Array.isArray(res.data)) {
|
|
156
|
+
data = res.data;
|
|
157
|
+
} else {
|
|
158
|
+
data = [];
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
if (isInitial) {
|
|
162
|
+
this.options = data;
|
|
163
|
+
} else {
|
|
164
|
+
this.options = this.options.concat(data);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
this.page.hasMore = data.length === this.page.size;
|
|
168
|
+
} catch (e) {
|
|
169
|
+
// 静默失败,避免影响表单使用;需要的话可由外层通过 requestFn 自行提示
|
|
170
|
+
this.page.hasMore = false;
|
|
171
|
+
}
|
|
172
|
+
},
|
|
173
|
+
handleFilter(val) {
|
|
174
|
+
this.page.key = val;
|
|
175
|
+
this.page.current = 1;
|
|
176
|
+
this.page.hasMore = true;
|
|
177
|
+
this.fetchData(true);
|
|
178
|
+
},
|
|
179
|
+
handleFocus() {
|
|
180
|
+
if (!this.page.key && this.options.length === 0) {
|
|
181
|
+
this.handleFilter('');
|
|
182
|
+
}
|
|
183
|
+
},
|
|
184
|
+
handleChange(val) {
|
|
185
|
+
this.$emit('input', val);
|
|
186
|
+
|
|
187
|
+
const findByValueKey = (v) => {
|
|
188
|
+
if (v === undefined || v === null) return null;
|
|
189
|
+
return this.options.find(item => item && item[this.valueKey] == v) || null;
|
|
190
|
+
};
|
|
191
|
+
|
|
192
|
+
let option = null;
|
|
193
|
+
if (this.multiple) {
|
|
194
|
+
if (Array.isArray(val)) {
|
|
195
|
+
option = val.map(v => findByValueKey(v)).filter(i => i != null);
|
|
196
|
+
} else {
|
|
197
|
+
option = [];
|
|
198
|
+
}
|
|
199
|
+
} else {
|
|
200
|
+
option = findByValueKey(val) || null;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
this.$emit('change', val);
|
|
204
|
+
this.$emit('canGetData', val, option);
|
|
205
|
+
}
|
|
206
|
+
},
|
|
207
|
+
};
|
|
208
|
+
</script>
|
|
209
|
+
|
package/src/index.js
CHANGED
|
@@ -19,6 +19,7 @@ import DatePickerPor from '../packages/date-picker-por/index.js'
|
|
|
19
19
|
import DynamicDescriptions from '../packages/dynamic-descriptions/index.js'
|
|
20
20
|
import SelectTreeUnit from '../packages/select-tree-unit/index.js'
|
|
21
21
|
import SelectTreeUnitForm from '../packages/select-tree-unit-form/index.js'
|
|
22
|
+
import ScrollLoadSelect from '../packages/scroll-load-select/index.js'
|
|
22
23
|
|
|
23
24
|
// 存储组件列表
|
|
24
25
|
const components = [
|
|
@@ -31,6 +32,7 @@ const components = [
|
|
|
31
32
|
PageHeader,
|
|
32
33
|
MultiCurrencyStatistics,
|
|
33
34
|
BranchBankSelect,
|
|
35
|
+
ScrollLoadSelect,
|
|
34
36
|
TabPage,
|
|
35
37
|
InputNumber,
|
|
36
38
|
DatePickerPor,
|
|
@@ -75,6 +77,7 @@ export {
|
|
|
75
77
|
TabPage,
|
|
76
78
|
MultiCurrencyStatistics,
|
|
77
79
|
BranchBankSelect,
|
|
80
|
+
ScrollLoadSelect,
|
|
78
81
|
InputNumber,
|
|
79
82
|
DatePickerPor,
|
|
80
83
|
DynamicDescriptions,
|