Commit 1cc28460da006084bf218f88ac96055717f868d0

Authored by 刘汉宸
1 parent 37b6b7d9

feat: 优化Select组件

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 => {
... ...