t20-common-lib 0.15.3 → 0.15.5
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,204 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<T20-Scroll-Load-Select
|
|
3
|
+
ref="scrollLoadSelect"
|
|
4
|
+
class="input-w"
|
|
5
|
+
v-model="_value"
|
|
6
|
+
v-bind="passThroughProps"
|
|
7
|
+
v-on="innerListeners"
|
|
8
|
+
@canGetData="handleCanGetData"
|
|
9
|
+
/>
|
|
10
|
+
</template>
|
|
11
|
+
|
|
12
|
+
<script>
|
|
13
|
+
import { getDataForGet, getDataForPost } from '../utils/request'
|
|
14
|
+
|
|
15
|
+
export default {
|
|
16
|
+
name: 'ScrollLoadSelect',
|
|
17
|
+
props: {
|
|
18
|
+
value: {
|
|
19
|
+
type: [String, Number, Array, Object],
|
|
20
|
+
default: undefined
|
|
21
|
+
},
|
|
22
|
+
items: {
|
|
23
|
+
type: Object,
|
|
24
|
+
default: () => ({})
|
|
25
|
+
},
|
|
26
|
+
label: {
|
|
27
|
+
type: String,
|
|
28
|
+
default: ''
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
computed: {
|
|
32
|
+
_value: {
|
|
33
|
+
get() {
|
|
34
|
+
return this.value
|
|
35
|
+
},
|
|
36
|
+
set(val) {
|
|
37
|
+
this.$emit('input', val)
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
innerListeners() {
|
|
41
|
+
const listeners = { ...this.$listeners }
|
|
42
|
+
delete listeners.canGetData
|
|
43
|
+
return listeners
|
|
44
|
+
},
|
|
45
|
+
runtimeLabelKey() {
|
|
46
|
+
return this.items?.api?.labelKey || this.items?.props?.labelKey || this.$attrs.labelKey || 'label'
|
|
47
|
+
},
|
|
48
|
+
runtimeValueKey() {
|
|
49
|
+
return this.items?.api?.valueKey || this.items?.props?.valueKey || this.$attrs.valueKey || 'value'
|
|
50
|
+
},
|
|
51
|
+
runtimeSearchKeyName() {
|
|
52
|
+
return this.items?.api?.searchKeyName || this.items?.props?.searchKeyName || this.$attrs.searchKeyName || 'searchKey'
|
|
53
|
+
},
|
|
54
|
+
runtimePageSize() {
|
|
55
|
+
return this.items?.api?.pageSize || this.items?.props?.pageSize || this.$attrs.pageSize || 20
|
|
56
|
+
},
|
|
57
|
+
runtimeSelectedLabel() {
|
|
58
|
+
return this.items?.props?.selectedLabel || this.$attrs.selectedLabel || this.label || ''
|
|
59
|
+
},
|
|
60
|
+
runtimeRequestFn() {
|
|
61
|
+
if (this.items?.api?.apiUrl && this.items?.api?.requestMethod) {
|
|
62
|
+
return this.fetchByApiConfig
|
|
63
|
+
}
|
|
64
|
+
return this.$attrs.requestFn || this.$attrs['request-fn'] || this.fetchByStaticOptions
|
|
65
|
+
},
|
|
66
|
+
shouldAutoLoad() {
|
|
67
|
+
const autoLoad = this.items?.props?.autoLoad ?? this.$attrs.autoLoad
|
|
68
|
+
return autoLoad !== false
|
|
69
|
+
},
|
|
70
|
+
passThroughProps() {
|
|
71
|
+
return {
|
|
72
|
+
...this.$attrs,
|
|
73
|
+
...(this.items?.props || {}),
|
|
74
|
+
requestFn: this.runtimeRequestFn,
|
|
75
|
+
labelKey: this.runtimeLabelKey,
|
|
76
|
+
valueKey: this.runtimeValueKey,
|
|
77
|
+
searchKeyName: this.runtimeSearchKeyName,
|
|
78
|
+
pageSize: this.runtimePageSize,
|
|
79
|
+
selectedLabel: this.runtimeSelectedLabel
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
mounted() {
|
|
84
|
+
this.triggerInitialRequest()
|
|
85
|
+
},
|
|
86
|
+
methods: {
|
|
87
|
+
triggerInitialRequest() {
|
|
88
|
+
if (!this.shouldAutoLoad) return
|
|
89
|
+
this.$nextTick(() => {
|
|
90
|
+
const instance = this.$refs.scrollLoadSelect
|
|
91
|
+
if (instance && typeof instance.handleFilter === 'function') {
|
|
92
|
+
instance.handleFilter('')
|
|
93
|
+
}
|
|
94
|
+
})
|
|
95
|
+
},
|
|
96
|
+
resolvePath(data, path) {
|
|
97
|
+
if (!path) return data
|
|
98
|
+
return String(path)
|
|
99
|
+
.split('.')
|
|
100
|
+
.reduce((acc, key) => (acc == null ? acc : acc[key]), data)
|
|
101
|
+
},
|
|
102
|
+
normalizeList(rawList) {
|
|
103
|
+
if (!Array.isArray(rawList)) return []
|
|
104
|
+
return rawList.map(item => {
|
|
105
|
+
if (!item || typeof item !== 'object') {
|
|
106
|
+
return {
|
|
107
|
+
[this.runtimeLabelKey]: String(item),
|
|
108
|
+
[this.runtimeValueKey]: item
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
return item
|
|
112
|
+
})
|
|
113
|
+
},
|
|
114
|
+
setDeepValue(target, path, value) {
|
|
115
|
+
const keys = String(path || '').split('.').filter(Boolean)
|
|
116
|
+
if (keys.length === 0) return
|
|
117
|
+
let cur = target
|
|
118
|
+
for (let i = 0; i < keys.length - 1; i += 1) {
|
|
119
|
+
const key = keys[i]
|
|
120
|
+
if (!cur[key] || typeof cur[key] !== 'object' || Array.isArray(cur[key])) {
|
|
121
|
+
cur[key] = {}
|
|
122
|
+
}
|
|
123
|
+
cur = cur[key]
|
|
124
|
+
}
|
|
125
|
+
cur[keys[keys.length - 1]] = value
|
|
126
|
+
},
|
|
127
|
+
buildPagingParams(params, apiConfig) {
|
|
128
|
+
const pageConfig = apiConfig?.page || {}
|
|
129
|
+
const currentKey = pageConfig.current || 'current'
|
|
130
|
+
const sizeKey = pageConfig.size || 'size'
|
|
131
|
+
const currentVal = params.current
|
|
132
|
+
const sizeVal = params.size
|
|
133
|
+
|
|
134
|
+
// 场景1:page: { current, size }
|
|
135
|
+
if (pageConfig.reqKey) {
|
|
136
|
+
return {
|
|
137
|
+
[pageConfig.reqKey]: {
|
|
138
|
+
[currentKey]: currentVal,
|
|
139
|
+
[sizeKey]: sizeVal
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// 场景2:page.current=xx&page.size=xx(支持点路径)
|
|
145
|
+
const pageParams = {}
|
|
146
|
+
this.setDeepValue(pageParams, currentKey, currentVal)
|
|
147
|
+
this.setDeepValue(pageParams, sizeKey, sizeVal)
|
|
148
|
+
return pageParams
|
|
149
|
+
},
|
|
150
|
+
async fetchByApiConfig(params = {}) {
|
|
151
|
+
const apiConfig = this.items?.api || {}
|
|
152
|
+
const method = String(apiConfig.requestMethod || '').toUpperCase()
|
|
153
|
+
const reqKeys = apiConfig.reqKeys || {}
|
|
154
|
+
const headerConfig = apiConfig.headerConfig || {}
|
|
155
|
+
const searchValue = params[this.runtimeSearchKeyName]
|
|
156
|
+
const pagingParams = this.buildPagingParams(params, apiConfig)
|
|
157
|
+
const requestData = {
|
|
158
|
+
...reqKeys,
|
|
159
|
+
...pagingParams
|
|
160
|
+
}
|
|
161
|
+
if (searchValue !== undefined) {
|
|
162
|
+
requestData[this.runtimeSearchKeyName] = searchValue
|
|
163
|
+
}
|
|
164
|
+
let res = null
|
|
165
|
+
if (method === 'GET') {
|
|
166
|
+
res = await getDataForGet(apiConfig.apiUrl, requestData, headerConfig)
|
|
167
|
+
} else if (method === 'POST') {
|
|
168
|
+
res = await getDataForPost(apiConfig.apiUrl, requestData, headerConfig)
|
|
169
|
+
} else {
|
|
170
|
+
return []
|
|
171
|
+
}
|
|
172
|
+
const list = apiConfig.dataProp ? this.resolvePath(res, apiConfig.dataProp) : (res && res.data)
|
|
173
|
+
return this.normalizeList(list)
|
|
174
|
+
},
|
|
175
|
+
async fetchByStaticOptions(params = {}) {
|
|
176
|
+
const sourceOptions = Array.isArray(this.items?.options) ? this.items.options : []
|
|
177
|
+
const current = Number(params.current || 1)
|
|
178
|
+
const size = Number(params.size || this.runtimePageSize || 20)
|
|
179
|
+
const searchValue = params[this.runtimeSearchKeyName]
|
|
180
|
+
const normalizedKeyword = searchValue == null ? '' : String(searchValue).toLowerCase()
|
|
181
|
+
const filtered = sourceOptions.filter(item => {
|
|
182
|
+
if (!normalizedKeyword) return true
|
|
183
|
+
const label = item && item[this.runtimeLabelKey]
|
|
184
|
+
return String(label == null ? '' : label).toLowerCase().includes(normalizedKeyword)
|
|
185
|
+
})
|
|
186
|
+
const start = (current - 1) * size
|
|
187
|
+
return filtered.slice(start, start + size)
|
|
188
|
+
},
|
|
189
|
+
handleCanGetData(val, option) {
|
|
190
|
+
if (Array.isArray(option)) {
|
|
191
|
+
const labels = option
|
|
192
|
+
.map(item => item && item[this.runtimeLabelKey])
|
|
193
|
+
.filter(label => label !== undefined && label !== null)
|
|
194
|
+
this.$emit('update:label', labels.join(','))
|
|
195
|
+
} else if (option && typeof option === 'object') {
|
|
196
|
+
this.$emit('update:label', option[this.runtimeLabelKey] || '')
|
|
197
|
+
} else if (val === '' || val === null || val === undefined) {
|
|
198
|
+
this.$emit('update:label', '')
|
|
199
|
+
}
|
|
200
|
+
this.$emit('canGetData', val, option)
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
</script>
|