Commit 1cc28460da006084bf218f88ac96055717f868d0
1 parent
37b6b7d9
Exists in
master
and in
3 other branches
feat: 优化Select组件
Showing
2 changed files
with
82 additions
and
88 deletions
Show diff stats
examples/views/docs/component/select.md
| ... | ... | @@ -246,10 +246,12 @@ export default { |
| 246 | 246 | console.log(val); |
| 247 | 247 | return new Promise(resolve => { |
| 248 | 248 | setTimeout(() => { |
| 249 | - resolve([ | |
| 250 | - { name: '王五', code: 'ww' }, | |
| 251 | - { name: '赵六', code: 'zl' }, | |
| 252 | - ]); | |
| 249 | + resolve({ | |
| 250 | + result: [ | |
| 251 | + { name: '王五', code: 'ww' }, | |
| 252 | + { name: '赵六', code: 'zl' }, | |
| 253 | + ] | |
| 254 | + }); | |
| 253 | 255 | }, 1000); |
| 254 | 256 | }); |
| 255 | 257 | }, |
| ... | ... | @@ -289,10 +291,12 @@ export default { |
| 289 | 291 | queryAPI(val) { |
| 290 | 292 | return new Promise(resolve => { |
| 291 | 293 | setTimeout(() => { |
| 292 | - resolve([ | |
| 293 | - { name: '王五', code: 'ww' }, | |
| 294 | - { name: '赵六', code: 'zl' }, | |
| 295 | - ]); | |
| 294 | + resolve({ | |
| 295 | + result: [ | |
| 296 | + { name: '王五', code: 'ww' }, | |
| 297 | + { name: '赵六', code: 'zl' }, | |
| 298 | + ] | |
| 299 | + }); | |
| 296 | 300 | }, 1000); |
| 297 | 301 | }); |
| 298 | 302 | }, |
| ... | ... | @@ -309,7 +313,7 @@ export default { |
| 309 | 313 | <template> |
| 310 | 314 | <div> |
| 311 | 315 | <pre class="demo-model" v-if="model.length">{{ model }}</pre> |
| 312 | - <z-select v-model="model" :queryApi="queryAPI" :options="options" multiple update></z-select> | |
| 316 | + <z-select v-model="model" :queryApi="queryAPI" :options="options" multiple update raw></z-select> | |
| 313 | 317 | </div> |
| 314 | 318 | </template> |
| 315 | 319 | |
| ... | ... | @@ -317,7 +321,11 @@ export default { |
| 317 | 321 | export default { |
| 318 | 322 | data() { |
| 319 | 323 | return { |
| 320 | - model: ['wq', 'cs'], | |
| 324 | + // model: ['wq', 'cs'], | |
| 325 | + model: [ | |
| 326 | + { name: '王七', code: 'wq' }, | |
| 327 | + { name: '陈拾', code: 'cs' }, | |
| 328 | + ], | |
| 321 | 329 | options: [ |
| 322 | 330 | { name: '王七', code: 'wq' }, |
| 323 | 331 | { name: '陈拾', code: 'cs' }, |
| ... | ... | @@ -328,10 +336,12 @@ export default { |
| 328 | 336 | queryAPI(val) { |
| 329 | 337 | return new Promise(resolve => { |
| 330 | 338 | setTimeout(() => { |
| 331 | - resolve([ | |
| 332 | - { name: '王五', code: 'ww' }, | |
| 333 | - { name: '赵六', code: 'zl' }, | |
| 334 | - ]); | |
| 339 | + resolve({ | |
| 340 | + result: [ | |
| 341 | + { name: '王五', code: 'ww' }, | |
| 342 | + { name: '赵六', code: 'zl' }, | |
| 343 | + ] | |
| 344 | + }); | |
| 335 | 345 | }, 1000); |
| 336 | 346 | }); |
| 337 | 347 | }, |
| ... | ... | @@ -369,12 +379,13 @@ export default { |
| 369 | 379 | methods: { |
| 370 | 380 | queryAPI(val) { |
| 371 | 381 | return new Promise(resolve => { |
| 372 | - this.label = ''; | |
| 373 | 382 | setTimeout(() => { |
| 374 | - resolve([ | |
| 375 | - { name: '王五', code: 'ww' }, | |
| 376 | - { name: '赵六', code: 'zl' }, | |
| 377 | - ]); | |
| 383 | + resolve({ | |
| 384 | + result: [ | |
| 385 | + { name: '王五', code: 'ww' }, | |
| 386 | + { name: '赵六', code: 'zl' }, | |
| 387 | + ] | |
| 388 | + }); | |
| 378 | 389 | }, 1000); |
| 379 | 390 | }); |
| 380 | 391 | }, |
| ... | ... | @@ -410,10 +421,12 @@ export default { |
| 410 | 421 | queryAPI(val) { |
| 411 | 422 | return new Promise(resolve => { |
| 412 | 423 | setTimeout(() => { |
| 413 | - resolve([ | |
| 414 | - { name: '王五', code: 'ww' }, | |
| 415 | - { name: '赵六', code: 'zl' }, | |
| 416 | - ]); | |
| 424 | + resolve({ | |
| 425 | + result: [ | |
| 426 | + { name: '王五', code: 'ww' }, | |
| 427 | + { name: '赵六', code: 'zl' }, | |
| 428 | + ] | |
| 429 | + }); | |
| 417 | 430 | }, 1000); |
| 418 | 431 | }); |
| 419 | 432 | }, |
| ... | ... | @@ -449,10 +462,12 @@ selectProps | Element Select组件参数 | Object | - | - |
| 449 | 462 | raw | 是否绑定原始对象 | Boolean | - | false |
| 450 | 463 | url | 远程搜索URL | String | - | - |
| 451 | 464 | http | HTTP请求库 | Function | - | - |
| 465 | +params | 请求参数 | Object | - | {} | |
| 452 | 466 | queryApi | 自定义接口 | Function | - | - |
| 453 | 467 | triggerSize | 触发远程搜索的字段长度 | Number | - | 0 |
| 454 | -auto | 初始化时自动查询数据 | Boolean | - | false | |
| 468 | +auto | 初始化时自动查询数据 | Boolean | - | true | |
| 455 | 469 | update | 点开下拉框时更新数据 | Boolean | - | false |
| 470 | +update-once | 点开下拉框时更新一次数据 | Boolean | - | false | |
| 456 | 471 | |
| 457 | 472 | ## Events 事件 |
| 458 | 473 | ... | ... |
packages/select/index.vue
| ... | ... | @@ -81,6 +81,16 @@ export default { |
| 81 | 81 | url: String, |
| 82 | 82 | // HTTP请求库 |
| 83 | 83 | http: Function, |
| 84 | + // 请求参数 | |
| 85 | + params: { | |
| 86 | + type: Object, | |
| 87 | + default: () => ({}), | |
| 88 | + }, | |
| 89 | + // 请求配置 | |
| 90 | + config: { | |
| 91 | + type: Object, | |
| 92 | + default: () => ({}), | |
| 93 | + }, | |
| 84 | 94 | // 自定义接口 |
| 85 | 95 | queryApi: Function, |
| 86 | 96 | // 触发远程搜索的字段长度 |
| ... | ... | @@ -88,8 +98,12 @@ export default { |
| 88 | 98 | type: Number, |
| 89 | 99 | default: 0, |
| 90 | 100 | }, |
| 91 | - auto: Boolean, | |
| 101 | + auto: { | |
| 102 | + type: Boolean, | |
| 103 | + default: true, | |
| 104 | + }, | |
| 92 | 105 | update: Boolean, |
| 106 | + updateOnce: Boolean, | |
| 93 | 107 | }, |
| 94 | 108 | data() { |
| 95 | 109 | return { |
| ... | ... | @@ -98,6 +112,7 @@ export default { |
| 98 | 112 | optionsCurrent: this.fixOptions(this.options), |
| 99 | 113 | loading: false, |
| 100 | 114 | initing: false, |
| 115 | + loaded: false, | |
| 101 | 116 | }; |
| 102 | 117 | }, |
| 103 | 118 | created() { |
| ... | ... | @@ -144,8 +159,14 @@ export default { |
| 144 | 159 | return { |
| 145 | 160 | ..._events, |
| 146 | 161 | 'visible-change': show => { |
| 147 | - if (this.remote && this.update && show) { | |
| 148 | - this.remoteMethod(); | |
| 162 | + if (this.remote && show) { | |
| 163 | + if (this.updateOnce) { | |
| 164 | + if (!this.loaded) { | |
| 165 | + this.remoteMethod(); | |
| 166 | + } | |
| 167 | + } else if (this.update) { | |
| 168 | + this.remoteMethod(); | |
| 169 | + } | |
| 149 | 170 | } |
| 150 | 171 | _events['visible-change'] && _events['visible-change'](show); |
| 151 | 172 | }, |
| ... | ... | @@ -155,64 +176,24 @@ export default { |
| 155 | 176 | methods: { |
| 156 | 177 | // 修复当前数据源包含当前选中项 |
| 157 | 178 | fixOptions(list) { |
| 158 | - if (!this.value || (this.value instanceof Array && this.value.length === 0) || (this.value instanceof Object && Object.keys(this.value).length === 0)) { | |
| 159 | - return list; | |
| 160 | - } | |
| 179 | + let fixOptions = []; | |
| 161 | 180 | if (this.raw) { |
| 162 | - // 绑定为对象值时修复默认项 | |
| 163 | - let fixOptions = []; | |
| 164 | - let defaultOptions = []; | |
| 165 | 181 | if (this.multiple) { |
| 166 | - fixOptions = [...this.value]; | |
| 167 | - this.options.forEach(item => { | |
| 168 | - if (this.value.find(i => i[this.valueKey] === item[this.valueKey])) { | |
| 169 | - defaultOptions.push(item); | |
| 170 | - } | |
| 171 | - }); | |
| 182 | + fixOptions = this.value && this.value.length > 0 ? [...this.value] : []; | |
| 172 | 183 | } else { |
| 173 | - fixOptions = [this.value]; | |
| 174 | - this.options.forEach(item => { | |
| 175 | - if (item[this.valueKey] === this.value[this.valueKey]) { | |
| 176 | - defaultOptions.push(item); | |
| 177 | - } | |
| 178 | - }); | |
| 184 | + fixOptions = this.value && Object.keys(this.value).length > 0 ? [this.value] : []; | |
| 179 | 185 | } |
| 180 | - let hash = {}; | |
| 181 | - const options = [...fixOptions, ...defaultOptions, ...list].reduce((result, item) => { | |
| 182 | - if (!hash[item[this.valueKey]]) { | |
| 183 | - // 如果当前元素的key值没有在hash对象里,则可放入最终结果数组 | |
| 184 | - hash[item[this.valueKey]] = true; // 把当前元素key值添加到hash对象 | |
| 185 | - result.push(item); // 把当前元素放入结果数组 | |
| 186 | - } | |
| 187 | - return result; // 返回结果数组 | |
| 188 | - }, []); | |
| 189 | - return options; | |
| 190 | - } else { | |
| 191 | - // 绑定为非对象值时修复默认项 | |
| 192 | - let defaultOptions = []; | |
| 193 | - if (this.multiple) { | |
| 194 | - this.options.forEach(item => { | |
| 195 | - if (this.value.find(i => i === item[this.valueKey])) { | |
| 196 | - defaultOptions.push(item); | |
| 197 | - } | |
| 198 | - }); | |
| 199 | - } else { | |
| 200 | - const targetOption = this.options.find(item => item[this.valueKey] === this.value); | |
| 201 | - if (targetOption) { | |
| 202 | - defaultOptions = [targetOption]; | |
| 203 | - } | |
| 204 | - } | |
| 205 | - let hash = {}; | |
| 206 | - const options = [...defaultOptions, ...list].reduce((result, item) => { | |
| 207 | - if (!hash[item[this.valueKey]]) { | |
| 208 | - // 如果当前元素的key值没有在hash对象里,则可放入最终结果数组 | |
| 209 | - hash[item[this.valueKey]] = true; // 把当前元素key值添加到hash对象 | |
| 210 | - result.push(item); // 把当前元素放入结果数组 | |
| 211 | - } | |
| 212 | - return result; // 返回结果数组 | |
| 213 | - }, []); | |
| 214 | - return options; | |
| 215 | 186 | } |
| 187 | + let hash = {}; | |
| 188 | + const options = [...fixOptions, ...this.options, ...list].reduce((result, item) => { | |
| 189 | + if (!hash[item[this.valueKey]]) { | |
| 190 | + // 如果当前元素的key值没有在hash对象里,则可放入最终结果数组 | |
| 191 | + hash[item[this.valueKey]] = true; // 把当前元素key值添加到hash对象 | |
| 192 | + item[this.valueKey] && item[this.labelKey] && result.push(item); // 把当前元素放入结果数组 | |
| 193 | + } | |
| 194 | + return result; // 返回结果数组 | |
| 195 | + }, []); | |
| 196 | + return options; | |
| 216 | 197 | }, |
| 217 | 198 | // 远程加载 |
| 218 | 199 | remoteMethod(val = '') { |
| ... | ... | @@ -226,23 +207,21 @@ export default { |
| 226 | 207 | requestPrimise = this.request({ |
| 227 | 208 | url: this.url, |
| 228 | 209 | method: 'get', |
| 229 | - params: searchText ? { [this.searchKey]: searchText } : {}, | |
| 210 | + params: searchText ? { [this.searchKey]: searchText, ...this.params } : this.params, | |
| 211 | + ...this.config, | |
| 230 | 212 | }); |
| 231 | 213 | } |
| 232 | 214 | requestPrimise |
| 233 | - .then(list => { | |
| 234 | - const options = this.fixOptions(list); | |
| 215 | + .then(res => { | |
| 216 | + const response = res || {}; | |
| 217 | + const options = this.fixOptions(response.result); | |
| 235 | 218 | this.optionsDataSource = options; |
| 236 | 219 | this.optionsCurrent = options; |
| 237 | - // 获取到选项数据源时刷新绑定显示值 | |
| 238 | - this.model = undefined; | |
| 239 | - this.$nextTick(() => { | |
| 240 | - this.model = this.value; | |
| 241 | - }); | |
| 242 | 220 | }) |
| 243 | 221 | .finally(() => { |
| 244 | 222 | this.loading = false; |
| 245 | 223 | this.initing = false; |
| 224 | + this.loaded = true; | |
| 246 | 225 | }); |
| 247 | 226 | } else { |
| 248 | 227 | this.optionsCurrent = this.optionsDataSource.filter(item => { | ... | ... |