@10yun/cv-mobile-ui 0.5.20 → 0.5.22

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.
Files changed (71) hide show
  1. package/package.json +1 -1
  2. package/plugins/jumps.js +57 -12
  3. package/plugins/lbs.js +17 -8
  4. package/ui-cv/components/cv-grid-item/cv-grid-item.vue +1 -1
  5. package/uni-ui/lib/uni-badge/uni-badge.vue +150 -1
  6. package/uni-ui/lib/uni-breadcrumb/uni-breadcrumb.vue +37 -1
  7. package/uni-ui/lib/uni-breadcrumb-item/uni-breadcrumb-item.vue +83 -1
  8. package/uni-ui/lib/uni-calendar/uni-calendar-item.vue +122 -1
  9. package/uni-ui/lib/uni-calendar/uni-calendar.vue +366 -1
  10. package/uni-ui/lib/uni-card/uni-card.vue +124 -1
  11. package/uni-ui/lib/uni-col/uni-col.vue +1 -1
  12. package/uni-ui/lib/uni-collapse/uni-collapse.vue +135 -1
  13. package/uni-ui/lib/uni-collapse-item/uni-collapse-item.vue +266 -1
  14. package/uni-ui/lib/uni-combox/uni-combox.vue +1 -1
  15. package/uni-ui/lib/uni-countdown/uni-countdown.vue +239 -1
  16. package/uni-ui/lib/uni-data-checkbox/uni-data-checkbox.vue +487 -1
  17. package/uni-ui/lib/uni-data-picker/uni-data-picker.vue +530 -1
  18. package/uni-ui/lib/uni-data-pickerview/uni-data-picker.js +157 -150
  19. package/uni-ui/lib/uni-data-pickerview/uni-data-pickerview.vue +166 -1
  20. package/uni-ui/lib/uni-data-select/uni-data-select.vue +289 -1
  21. package/uni-ui/lib/uni-datetime-picker/calendar-item.vue +70 -1
  22. package/uni-ui/lib/uni-datetime-picker/calendar.vue +629 -1
  23. package/uni-ui/lib/uni-datetime-picker/time-picker.vue +741 -1
  24. package/uni-ui/lib/uni-datetime-picker/uni-datetime-picker.vue +847 -1
  25. package/uni-ui/lib/uni-drawer/uni-drawer.vue +115 -1
  26. package/uni-ui/lib/uni-easyinput/uni-easyinput.vue +515 -1
  27. package/uni-ui/lib/uni-fab/uni-fab.vue +257 -1
  28. package/uni-ui/lib/uni-fav/uni-fav.vue +123 -1
  29. package/uni-ui/lib/uni-file-picker/uni-file-picker.vue +642 -1
  30. package/uni-ui/lib/uni-file-picker/upload-file.vue +177 -1
  31. package/uni-ui/lib/uni-file-picker/upload-image.vue +176 -1
  32. package/uni-ui/lib/uni-forms/uni-forms.vue +375 -1
  33. package/uni-ui/lib/uni-forms-item/uni-forms-item.vue +429 -1
  34. package/uni-ui/lib/uni-goods-nav/uni-goods-nav.vue +129 -1
  35. package/uni-ui/lib/uni-grid/uni-grid.vue +115 -1
  36. package/uni-ui/lib/uni-grid-item/uni-grid-item.vue +78 -1
  37. package/uni-ui/lib/uni-group/uni-group.vue +85 -1
  38. package/uni-ui/lib/uni-icons/uni-icons.vue +85 -1
  39. package/uni-ui/lib/uni-indexed-list/uni-indexed-list-item.vue +68 -1
  40. package/uni-ui/lib/uni-indexed-list/uni-indexed-list.vue +294 -1
  41. package/uni-ui/lib/uni-list/uni-list.vue +81 -1
  42. package/uni-ui/lib/uni-list-ad/uni-list-ad.vue +77 -1
  43. package/uni-ui/lib/uni-list-chat/uni-list-chat.vue +294 -1
  44. package/uni-ui/lib/uni-list-item/uni-list-item.vue +346 -1
  45. package/uni-ui/lib/uni-load-more/uni-load-more.vue +172 -1
  46. package/uni-ui/lib/uni-nav-bar/uni-nav-bar.vue +205 -1
  47. package/uni-ui/lib/uni-nav-bar/uni-status-bar.vue +18 -1
  48. package/uni-ui/lib/uni-notice-bar/uni-notice-bar.vue +331 -1
  49. package/uni-ui/lib/uni-number-box/uni-number-box.vue +166 -1
  50. package/uni-ui/lib/uni-pagination/uni-pagination.vue +323 -1
  51. package/uni-ui/lib/uni-popup/uni-popup.vue +1 -1
  52. package/uni-ui/lib/uni-popup-dialog/uni-popup-dialog.vue +173 -1
  53. package/uni-ui/lib/uni-popup-message/uni-popup-message.vue +74 -1
  54. package/uni-ui/lib/uni-popup-share/uni-popup-share.vue +106 -1
  55. package/uni-ui/lib/uni-rate/uni-rate.vue +322 -1
  56. package/uni-ui/lib/uni-row/uni-row.vue +1 -1
  57. package/uni-ui/lib/uni-search-bar/uni-search-bar.vue +236 -1
  58. package/uni-ui/lib/uni-section/uni-section.vue +109 -1
  59. package/uni-ui/lib/uni-segmented-control/uni-segmented-control.vue +103 -1
  60. package/uni-ui/lib/uni-status-bar/uni-status-bar.vue +1 -1
  61. package/uni-ui/lib/uni-steps/uni-steps.vue +120 -1
  62. package/uni-ui/lib/uni-swipe-action-item/uni-swipe-action-item.vue +226 -3
  63. package/uni-ui/lib/uni-swiper-dot/uni-swiper-dot.vue +167 -1
  64. package/uni-ui/lib/uni-table/uni-table.vue +297 -1
  65. package/uni-ui/lib/uni-tag/uni-tag.vue +100 -1
  66. package/uni-ui/lib/uni-td/uni-td.vue +78 -1
  67. package/uni-ui/lib/uni-th/filter-dropdown.vue +1 -1
  68. package/uni-ui/lib/uni-th/uni-th.vue +224 -1
  69. package/uni-ui/lib/uni-thead/uni-thead.vue +77 -1
  70. package/uni-ui/lib/uni-tr/table-checkbox.vue +79 -1
  71. package/uni-ui/lib/uni-tr/uni-tr.vue +135 -1
@@ -1 +1,487 @@
1
- <template>
2
1
  <view class="uni-data-checklist" :style="{ 'margin-top': isTop + 'px' }">
3
2
  <template v-if="!isLocal">
4
3
  <view class="uni-data-loading">
5
4
  <uni-load-more
6
5
  v-if="!mixinDatacomErrorMessage"
7
6
  status="loading"
8
7
  iconType="snow"
9
8
  :iconSize="18"
10
9
  :content-text="contentText"
11
10
  ></uni-load-more>
12
11
  <text v-else>{{ mixinDatacomErrorMessage }}</text>
13
12
  </view>
14
13
  </template>
15
14
  <template v-else>
16
15
  <checkbox-group v-if="multiple" class="checklist-group" :class="{ 'is-list': mode === 'list' || wrap }" @change="chagne">
17
16
  <label
18
17
  class="checklist-box"
19
18
  :class="[
20
19
  'is--' + mode,
21
20
  item.selected ? 'is-checked' : '',
22
21
  disabled || !!item.disabled ? 'is-disable' : '',
23
22
  index !== 0 && mode === 'list' ? 'is-list-border' : ''
24
23
  ]"
25
24
  :style="item.styleBackgroud"
26
25
  v-for="(item, index) in dataList"
27
26
  :key="index"
28
27
  >
29
28
  <checkbox
30
29
  class="hidden"
31
30
  hidden
32
31
  :disabled="disabled || !!item.disabled"
33
32
  :value="item[map.value] + ''"
34
33
  :checked="item.selected"
35
34
  />
36
35
  <view
37
36
  v-if="(mode !== 'tag' && mode !== 'list') || (mode === 'list' && icon === 'left')"
38
37
  class="checkbox__inner"
39
38
  :style="item.styleIcon"
40
39
  >
41
40
  <view class="checkbox__inner-icon"></view>
42
41
  </view>
43
42
  <view class="checklist-content" :class="{ 'list-content': mode === 'list' && icon === 'left' }">
44
43
  <text class="checklist-text" :style="item.styleIconText">{{ item[map.text] }}</text>
45
44
  <view v-if="mode === 'list' && icon === 'right'" class="checkobx__list" :style="item.styleBackgroud"></view>
46
45
  </view>
47
46
  </label>
48
47
  </checkbox-group>
49
48
  <radio-group v-else class="checklist-group" :class="{ 'is-list': mode === 'list', 'is-wrap': wrap }" @change="chagne">
50
49
  <!-- -->
51
50
  <label
52
51
  class="checklist-box"
53
52
  :class="[
54
53
  'is--' + mode,
55
54
  item.selected ? 'is-checked' : '',
56
55
  disabled || !!item.disabled ? 'is-disable' : '',
57
56
  index !== 0 && mode === 'list' ? 'is-list-border' : ''
58
57
  ]"
59
58
  :style="item.styleBackgroud"
60
59
  v-for="(item, index) in dataList"
61
60
  :key="index"
62
61
  >
63
62
  <radio
64
63
  class="hidden"
65
64
  hidden
66
65
  :disabled="disabled || item.disabled"
67
66
  :value="item[map.value] + ''"
68
67
  :checked="item.selected"
69
68
  />
70
69
  <view
71
70
  v-if="(mode !== 'tag' && mode !== 'list') || (mode === 'list' && icon === 'left')"
72
71
  class="radio__inner"
73
72
  :style="item.styleBackgroud"
74
73
  >
75
74
  <view class="radio__inner-icon" :style="item.styleIcon"></view>
76
75
  </view>
77
76
  <view class="checklist-content" :class="{ 'list-content': mode === 'list' && icon === 'left' }">
78
77
  <text class="checklist-text" :style="item.styleIconText">{{ item[map.text] }}</text>
79
78
  <view v-if="mode === 'list' && icon === 'right'" :style="item.styleRightIcon" class="checkobx__list"></view>
80
79
  </view>
81
80
  </label>
82
81
  </radio-group>
83
82
  </template>
84
83
  </view>
85
84
  * DataChecklist 数据选择器
86
85
  * @description 通过数据渲染 checkbox 和 radio
87
86
  * @tutorial https://ext.dcloud.net.cn/plugin?id=xxx
88
87
  * @property {String} mode = [default| list | button | tag] 显示模式
89
88
  * @value default 默认横排模式
90
89
  * @value list 列表模式
91
90
  * @value button 按钮模式
92
91
  * @value tag 标签模式
93
92
  * @property {Boolean} multiple = [true|false] 是否多选
94
93
  * @property {Array|String|Number} value 默认值
95
94
  * @property {Array} localdata 本地数据 ,格式 [{text:'',value:''}]
96
95
  * @property {Number|String} min 最小选择个数 ,multiple为true时生效
97
96
  * @property {Number|String} max 最大选择个数 ,multiple为true时生效
98
97
  * @property {Boolean} wrap 是否换行显示
99
98
  * @property {String} icon = [left|right] list 列表模式下icon显示位置
100
99
  * @property {Boolean} selectedColor 选中颜色
101
100
  * @property {Boolean} emptyText 没有数据时显示的文字 ,本地数据无效
102
101
  * @property {Boolean} selectedTextColor 选中文本颜色,如不填写则自动显示
103
102
  * @property {Object} map 字段映射, 默认 map={text:'text',value:'value'}
104
103
  * @value left 左侧显示
105
104
  * @value right 右侧显示
106
105
  * @event {Function} change 选中发生变化触发
107
106
  */
108
107
  name: 'uniDataChecklist',
109
108
  mixins: [uniCloud.mixinDatacom || {}],
110
109
  emits: ['input', 'update:modelValue', 'change'],
111
110
  props: {
112
111
  mode: {
113
112
  type: String,
114
113
  default: 'default'
115
114
  },
116
115
  multiple: {
117
116
  type: Boolean,
118
117
  default: false
119
118
  },
120
119
  value: {
121
120
  type: [Array, String, Number],
122
121
  default() {
123
122
  return '';
124
123
  }
125
124
  },
126
125
  // TODO vue3
127
126
  modelValue: {
128
127
  type: [Array, String, Number],
129
128
  default() {
130
129
  return '';
131
130
  }
132
131
  },
133
132
  localdata: {
134
133
  type: Array,
135
134
  default() {
136
135
  return [];
137
136
  }
138
137
  },
139
138
  min: {
140
139
  type: [Number, String],
141
140
  default: ''
142
141
  },
143
142
  max: {
144
143
  type: [Number, String],
145
144
  default: ''
146
145
  },
147
146
  wrap: {
148
147
  type: Boolean,
149
148
  default: false
150
149
  },
151
150
  icon: {
152
151
  type: String,
153
152
  default: 'left'
154
153
  },
155
154
  selectedColor: {
156
155
  type: String,
157
156
  default: ''
158
157
  },
159
158
  selectedTextColor: {
160
159
  type: String,
161
160
  default: ''
162
161
  },
163
162
  emptyText: {
164
163
  type: String,
165
164
  default: '暂无数据'
166
165
  },
167
166
  disabled: {
168
167
  type: Boolean,
169
168
  default: false
170
169
  },
171
170
  map: {
172
171
  type: Object,
173
172
  default() {
174
173
  return {
175
174
  text: 'text',
176
175
  value: 'value'
177
176
  };
178
177
  }
179
178
  }
180
179
  },
181
180
  watch: {
182
181
  localdata: {
183
182
  handler(newVal) {
184
183
  this.range = newVal;
185
184
  this.dataList = this.getDataList(this.getSelectedValue(newVal));
186
185
  },
187
186
  deep: true
188
187
  },
189
188
  mixinDatacomResData(newVal) {
190
189
  this.range = newVal;
191
190
  this.dataList = this.getDataList(this.getSelectedValue(newVal));
192
191
  },
193
192
  value(newVal) {
194
193
  this.dataList = this.getDataList(newVal);
195
194
  // fix by mehaotian is_reset 在 uni-forms 中定义
196
195
  // if(!this.is_reset){
197
196
  // this.is_reset = false
198
197
  // this.formItem && this.formItem.setValue(newVal)
199
198
  // }
200
199
  },
201
200
  modelValue(newVal) {
202
201
  this.dataList = this.getDataList(newVal);
203
202
  // if(!this.is_reset){
204
203
  // this.is_reset = false
205
204
  // this.formItem && this.formItem.setValue(newVal)
206
205
  // }
207
206
  }
208
207
  },
209
208
  data() {
210
209
  return {
211
210
  dataList: [],
212
211
  range: [],
213
212
  contentText: {
214
213
  contentdown: '查看更多',
215
214
  contentrefresh: '加载中',
216
215
  contentnomore: '没有更多'
217
216
  },
218
217
  isLocal: true,
219
218
  styles: {
220
219
  selectedColor: '#2979ff',
221
220
  selectedTextColor: '#666'
222
221
  },
223
222
  isTop: 0
224
223
  };
225
224
  },
226
225
  computed: {
227
226
  dataValue() {
228
227
  if (this.value === '') return this.modelValue;
229
228
  if (this.modelValue === '') return this.value;
230
229
  return this.value;
231
230
  }
232
231
  },
233
232
  created() {
234
233
  // this.form = this.getForm('uniForms')
235
234
  // this.formItem = this.getForm('uniFormsItem')
236
235
  // this.formItem && this.formItem.setValue(this.value)
237
236
  // if (this.formItem) {
238
237
  // this.isTop = 6
239
238
  // if (this.formItem.name) {
240
239
  // // 如果存在name添加默认值,否则formData 中不存在这个字段不校验
241
240
  // if(!this.is_reset){
242
241
  // this.is_reset = false
243
242
  // this.formItem.setValue(this.dataValue)
244
243
  // }
245
244
  // this.rename = this.formItem.name
246
245
  // this.form.inputChildrens.push(this)
247
246
  // }
248
247
  // }
249
248
  if (this.localdata && this.localdata.length !== 0) {
250
249
  this.isLocal = true;
251
250
  this.range = this.localdata;
252
251
  this.dataList = this.getDataList(this.getSelectedValue(this.range));
253
252
  } else {
254
253
  if (this.collection) {
255
254
  this.isLocal = false;
256
255
  this.loadData();
257
256
  }
258
257
  }
259
258
  },
260
259
  methods: {
261
260
  loadData() {
262
261
  this.mixinDatacomGet()
263
262
  .then((res) => {
264
263
  this.mixinDatacomResData = res.result.data;
265
264
  if (this.mixinDatacomResData.length === 0) {
266
265
  this.isLocal = false;
267
266
  this.mixinDatacomErrorMessage = this.emptyText;
268
267
  } else {
269
268
  this.isLocal = true;
270
269
  }
271
270
  })
272
271
  .catch((err) => {
273
272
  this.mixinDatacomErrorMessage = err.message;
274
273
  });
275
274
  },
276
275
  /**
277
276
  * 获取父元素实例
278
277
  */
279
278
  getForm(name = 'uniForms') {
280
279
  let parent = this.$parent;
281
280
  let parentName = parent.$options.name;
282
281
  while (parentName !== name) {
283
282
  parent = parent.$parent;
284
283
  if (!parent) return false;
285
284
  parentName = parent.$options.name;
286
285
  }
287
286
  return parent;
288
287
  },
289
288
  chagne(e) {
290
289
  const values = e.detail.value;
291
290
  let detail = {
292
291
  value: [],
293
292
  data: []
294
293
  };
295
294
  if (this.multiple) {
296
295
  this.range.forEach((item) => {
297
296
  if (values.includes(item[this.map.value] + '')) {
298
297
  detail.value.push(item[this.map.value]);
299
298
  detail.data.push(item);
300
299
  }
301
300
  });
302
301
  } else {
303
302
  const range = this.range.find((item) => item[this.map.value] + '' === values);
304
303
  if (range) {
305
304
  detail = {
306
305
  value: range[this.map.value],
307
306
  data: range
308
307
  };
309
308
  }
310
309
  }
311
310
  // this.formItem && this.formItem.setValue(detail.value)
312
311
  // TODO 兼容 vue2
313
312
  this.$emit('input', detail.value);
314
313
  // // TOTO 兼容 vue3
315
314
  this.$emit('update:modelValue', detail.value);
316
315
  this.$emit('change', {
317
316
  detail
318
317
  });
319
318
  if (this.multiple) {
320
319
  // 如果 v-model 没有绑定 ,则走内部逻辑
321
320
  // if (this.value.length === 0) {
322
321
  this.dataList = this.getDataList(detail.value, true);
323
322
  // }
324
323
  } else {
325
324
  this.dataList = this.getDataList(detail.value);
326
325
  }
327
326
  },
328
327
  /**
329
328
  * 获取渲染的新数组
330
329
  * @param {Object} value 选中内容
331
330
  */
332
331
  getDataList(value) {
333
332
  // 解除引用关系,破坏原引用关系,避免污染源数据
334
333
  let dataList = JSON.parse(JSON.stringify(this.range));
335
334
  let list = [];
336
335
  if (this.multiple) {
337
336
  if (!Array.isArray(value)) {
338
337
  value = [];
339
338
  }
340
339
  }
341
340
  dataList.forEach((item, index) => {
342
341
  item.disabled = item.disable || item.disabled || false;
343
342
  if (this.multiple) {
344
343
  if (value.length > 0) {
345
344
  let have = value.find((val) => val === item[this.map.value]);
346
345
  item.selected = have !== undefined;
347
346
  } else {
348
347
  item.selected = false;
349
348
  }
350
349
  } else {
351
350
  item.selected = value === item[this.map.value];
352
351
  }
353
352
  list.push(item);
354
353
  });
355
354
  return this.setRange(list);
356
355
  },
357
356
  /**
358
357
  * 处理最大最小值
359
358
  * @param {Object} list
360
359
  */
361
360
  setRange(list) {
362
361
  let selectList = list.filter((item) => item.selected);
363
362
  let min = Number(this.min) || 0;
364
363
  let max = Number(this.max) || '';
365
364
  list.forEach((item, index) => {
366
365
  if (this.multiple) {
367
366
  if (selectList.length <= min) {
368
367
  let have = selectList.find((val) => val[this.map.value] === item[this.map.value]);
369
368
  if (have !== undefined) {
370
369
  item.disabled = true;
371
370
  }
372
371
  }
373
372
  if (selectList.length >= max && max !== '') {
374
373
  let have = selectList.find((val) => val[this.map.value] === item[this.map.value]);
375
374
  if (have === undefined) {
376
375
  item.disabled = true;
377
376
  }
378
377
  }
379
378
  }
380
379
  this.setStyles(item, index);
381
380
  list[index] = item;
382
381
  });
383
382
  return list;
384
383
  },
385
384
  /**
386
385
  * 设置 class
387
386
  * @param {Object} item
388
387
  * @param {Object} index
389
388
  */
390
389
  setStyles(item, index) {
391
390
  // 设置自定义样式
392
391
  item.styleBackgroud = this.setStyleBackgroud(item);
393
392
  item.styleIcon = this.setStyleIcon(item);
394
393
  item.styleIconText = this.setStyleIconText(item);
395
394
  item.styleRightIcon = this.setStyleRightIcon(item);
396
395
  },
397
396
  /**
398
397
  * 获取选中值
399
398
  * @param {Object} range
400
399
  */
401
400
  getSelectedValue(range) {
402
401
  if (!this.multiple) return this.dataValue;
403
402
  let selectedArr = [];
404
403
  range.forEach((item) => {
405
404
  if (item.selected) {
406
405
  selectedArr.push(item[this.map.value]);
407
406
  }
408
407
  });
409
408
  return this.dataValue.length > 0 ? this.dataValue : selectedArr;
410
409
  },
411
410
  /**
412
411
  * 设置背景样式
413
412
  */
414
413
  setStyleBackgroud(item) {
415
414
  let styles = {};
416
415
  let selectedColor = this.selectedColor ? this.selectedColor : '#2979ff';
417
416
  if (this.selectedColor) {
418
417
  if (this.mode !== 'list') {
419
418
  styles['border-color'] = item.selected ? selectedColor : '#DCDFE6';
420
419
  }
421
420
  if (this.mode === 'tag') {
422
421
  styles['background-color'] = item.selected ? selectedColor : '#f5f5f5';
423
422
  }
424
423
  }
425
424
  let classles = '';
426
425
  for (let i in styles) {
427
426
  classles += `${i}:${styles[i]};`;
428
427
  }
429
428
  return classles;
430
429
  },
431
430
  setStyleIcon(item) {
432
431
  let styles = {};
433
432
  let classles = '';
434
433
  if (this.selectedColor) {
435
434
  let selectedColor = this.selectedColor ? this.selectedColor : '#2979ff';
436
435
  styles['background-color'] = item.selected ? selectedColor : '#fff';
437
436
  styles['border-color'] = item.selected ? selectedColor : '#DCDFE6';
438
437
  if (!item.selected && item.disabled) {
439
438
  styles['background-color'] = '#F2F6FC';
440
439
  styles['border-color'] = item.selected ? selectedColor : '#DCDFE6';
441
440
  }
442
441
  }
443
442
  for (let i in styles) {
444
443
  classles += `${i}:${styles[i]};`;
445
444
  }
446
445
  return classles;
447
446
  },
448
447
  setStyleIconText(item) {
449
448
  let styles = {};
450
449
  let classles = '';
451
450
  if (this.selectedColor) {
452
451
  let selectedColor = this.selectedColor ? this.selectedColor : '#2979ff';
453
452
  if (this.mode === 'tag') {
454
453
  styles.color = item.selected ? (this.selectedTextColor ? this.selectedTextColor : '#fff') : '#666';
455
454
  } else {
456
455
  styles.color = item.selected ? (this.selectedTextColor ? this.selectedTextColor : selectedColor) : '#666';
457
456
  }
458
457
  if (!item.selected && item.disabled) {
459
458
  styles.color = '#999';
460
459
  }
461
460
  }
462
461
  for (let i in styles) {
463
462
  classles += `${i}:${styles[i]};`;
464
463
  }
465
464
  return classles;
466
465
  },
467
466
  setStyleRightIcon(item) {
468
467
  let styles = {};
469
468
  let classles = '';
470
469
  if (this.mode === 'list') {
471
470
  styles['border-color'] = item.selected ? this.styles.selectedColor : '#DCDFE6';
472
471
  }
473
472
  for (let i in styles) {
474
473
  classles += `${i}:${styles[i]};`;
475
474
  }
476
475
  return classles;
477
476
  }
478
477
  }
478
+ <template>
479
+ <view class="uni-data-checklist" :style="{ 'margin-top': isTop + 'px' }">
480
+ <template v-if="!isLocal">
481
+ <view class="uni-data-loading">
482
+ <uni-load-more
483
+ v-if="!mixinDatacomErrorMessage"
484
+ status="loading"
485
+ iconType="snow"
486
+ :iconSize="18"
487
+ :content-text="contentText"
488
+ ></uni-load-more>
489
+ <text v-else>{{ mixinDatacomErrorMessage }}</text>
490
+ </view>
491
+ </template>
492
+ <template v-else>
493
+ <checkbox-group v-if="multiple" class="checklist-group" :class="{ 'is-list': mode === 'list' || wrap }" @change="chagne">
494
+ <label
495
+ class="checklist-box"
496
+ :class="[
497
+ 'is--' + mode,
498
+ item.selected ? 'is-checked' : '',
499
+ disabled || !!item.disabled ? 'is-disable' : '',
500
+ index !== 0 && mode === 'list' ? 'is-list-border' : ''
501
+ ]"
502
+ :style="item.styleBackgroud"
503
+ v-for="(item, index) in dataList"
504
+ :key="index"
505
+ >
506
+ <checkbox
507
+ class="hidden"
508
+ hidden
509
+ :disabled="disabled || !!item.disabled"
510
+ :value="item[map.value] + ''"
511
+ :checked="item.selected"
512
+ />
513
+ <view
514
+ v-if="(mode !== 'tag' && mode !== 'list') || (mode === 'list' && icon === 'left')"
515
+ class="checkbox__inner"
516
+ :style="item.styleIcon"
517
+ >
518
+ <view class="checkbox__inner-icon"></view>
519
+ </view>
520
+ <view class="checklist-content" :class="{ 'list-content': mode === 'list' && icon === 'left' }">
521
+ <text class="checklist-text" :style="item.styleIconText">{{ item[map.text] }}</text>
522
+ <view v-if="mode === 'list' && icon === 'right'" class="checkobx__list" :style="item.styleBackgroud"></view>
523
+ </view>
524
+ </label>
525
+ </checkbox-group>
526
+ <radio-group v-else class="checklist-group" :class="{ 'is-list': mode === 'list', 'is-wrap': wrap }" @change="chagne">
527
+ <!-- -->
528
+ <label
529
+ class="checklist-box"
530
+ :class="[
531
+ 'is--' + mode,
532
+ item.selected ? 'is-checked' : '',
533
+ disabled || !!item.disabled ? 'is-disable' : '',
534
+ index !== 0 && mode === 'list' ? 'is-list-border' : ''
535
+ ]"
536
+ :style="item.styleBackgroud"
537
+ v-for="(item, index) in dataList"
538
+ :key="index"
539
+ >
540
+ <radio
541
+ class="hidden"
542
+ hidden
543
+ :disabled="disabled || item.disabled"
544
+ :value="item[map.value] + ''"
545
+ :checked="item.selected"
546
+ />
547
+ <view
548
+ v-if="(mode !== 'tag' && mode !== 'list') || (mode === 'list' && icon === 'left')"
549
+ class="radio__inner"
550
+ :style="item.styleBackgroud"
551
+ >
552
+ <view class="radio__inner-icon" :style="item.styleIcon"></view>
553
+ </view>
554
+ <view class="checklist-content" :class="{ 'list-content': mode === 'list' && icon === 'left' }">
555
+ <text class="checklist-text" :style="item.styleIconText">{{ item[map.text] }}</text>
556
+ <view v-if="mode === 'list' && icon === 'right'" :style="item.styleRightIcon" class="checkobx__list"></view>
557
+ </view>
558
+ </label>
559
+ </radio-group>
560
+ </template>
561
+ </view>
562
+ </template>
563
+ <script>
564
+ /**
565
+ * DataChecklist 数据选择器
566
+ * @description 通过数据渲染 checkbox 和 radio
567
+ * @tutorial https://ext.dcloud.net.cn/plugin?id=xxx
568
+ * @property {String} mode = [default| list | button | tag] 显示模式
569
+ * @value default 默认横排模式
570
+ * @value list 列表模式
571
+ * @value button 按钮模式
572
+ * @value tag 标签模式
573
+ * @property {Boolean} multiple = [true|false] 是否多选
574
+ * @property {Array|String|Number} value 默认值
575
+ * @property {Array} localdata 本地数据 ,格式 [{text:'',value:''}]
576
+ * @property {Number|String} min 最小选择个数 ,multiple为true时生效
577
+ * @property {Number|String} max 最大选择个数 ,multiple为true时生效
578
+ * @property {Boolean} wrap 是否换行显示
579
+ * @property {String} icon = [left|right] list 列表模式下icon显示位置
580
+ * @property {Boolean} selectedColor 选中颜色
581
+ * @property {Boolean} emptyText 没有数据时显示的文字 ,本地数据无效
582
+ * @property {Boolean} selectedTextColor 选中文本颜色,如不填写则自动显示
583
+ * @property {Object} map 字段映射, 默认 map={text:'text',value:'value'}
584
+ * @value left 左侧显示
585
+ * @value right 右侧显示
586
+ * @event {Function} change 选中发生变化触发
587
+ */
588
+ export default {
589
+ name: 'uniDataChecklist',
590
+ mixins: [uniCloud.mixinDatacom || {}],
591
+ emits: ['input', 'update:modelValue', 'change'],
592
+ props: {
593
+ mode: {
594
+ type: String,
595
+ default: 'default'
596
+ },
597
+ multiple: {
598
+ type: Boolean,
599
+ default: false
600
+ },
601
+ value: {
602
+ type: [Array, String, Number],
603
+ default() {
604
+ return '';
605
+ }
606
+ },
607
+ // TODO vue3
608
+ modelValue: {
609
+ type: [Array, String, Number],
610
+ default() {
611
+ return '';
612
+ }
613
+ },
614
+ localdata: {
615
+ type: Array,
616
+ default() {
617
+ return [];
618
+ }
619
+ },
620
+ min: {
621
+ type: [Number, String],
622
+ default: ''
623
+ },
624
+ max: {
625
+ type: [Number, String],
626
+ default: ''
627
+ },
628
+ wrap: {
629
+ type: Boolean,
630
+ default: false
631
+ },
632
+ icon: {
633
+ type: String,
634
+ default: 'left'
635
+ },
636
+ selectedColor: {
637
+ type: String,
638
+ default: ''
639
+ },
640
+ selectedTextColor: {
641
+ type: String,
642
+ default: ''
643
+ },
644
+ emptyText: {
645
+ type: String,
646
+ default: '暂无数据'
647
+ },
648
+ disabled: {
649
+ type: Boolean,
650
+ default: false
651
+ },
652
+ map: {
653
+ type: Object,
654
+ default() {
655
+ return {
656
+ text: 'text',
657
+ value: 'value'
658
+ };
659
+ }
660
+ }
661
+ },
662
+ watch: {
663
+ localdata: {
664
+ handler(newVal) {
665
+ this.range = newVal;
666
+ this.dataList = this.getDataList(this.getSelectedValue(newVal));
667
+ },
668
+ deep: true
669
+ },
670
+ mixinDatacomResData(newVal) {
671
+ this.range = newVal;
672
+ this.dataList = this.getDataList(this.getSelectedValue(newVal));
673
+ },
674
+ value(newVal) {
675
+ this.dataList = this.getDataList(newVal);
676
+ // fix by mehaotian is_reset 在 uni-forms 中定义
677
+ // if(!this.is_reset){
678
+ // this.is_reset = false
679
+ // this.formItem && this.formItem.setValue(newVal)
680
+ // }
681
+ },
682
+ modelValue(newVal) {
683
+ this.dataList = this.getDataList(newVal);
684
+ // if(!this.is_reset){
685
+ // this.is_reset = false
686
+ // this.formItem && this.formItem.setValue(newVal)
687
+ // }
688
+ }
689
+ },
690
+ data() {
691
+ return {
692
+ dataList: [],
693
+ range: [],
694
+ contentText: {
695
+ contentdown: '查看更多',
696
+ contentrefresh: '加载中',
697
+ contentnomore: '没有更多'
698
+ },
699
+ isLocal: true,
700
+ styles: {
701
+ selectedColor: '#2979ff',
702
+ selectedTextColor: '#666'
703
+ },
704
+ isTop: 0
705
+ };
706
+ },
707
+ computed: {
708
+ dataValue() {
709
+ if (this.value === '') return this.modelValue;
710
+ if (this.modelValue === '') return this.value;
711
+ return this.value;
712
+ }
713
+ },
714
+ created() {
715
+ // this.form = this.getForm('uniForms')
716
+ // this.formItem = this.getForm('uniFormsItem')
717
+ // this.formItem && this.formItem.setValue(this.value)
718
+ // if (this.formItem) {
719
+ // this.isTop = 6
720
+ // if (this.formItem.name) {
721
+ // // 如果存在name添加默认值,否则formData 中不存在这个字段不校验
722
+ // if(!this.is_reset){
723
+ // this.is_reset = false
724
+ // this.formItem.setValue(this.dataValue)
725
+ // }
726
+ // this.rename = this.formItem.name
727
+ // this.form.inputChildrens.push(this)
728
+ // }
729
+ // }
730
+ if (this.localdata && this.localdata.length !== 0) {
731
+ this.isLocal = true;
732
+ this.range = this.localdata;
733
+ this.dataList = this.getDataList(this.getSelectedValue(this.range));
734
+ } else {
735
+ if (this.collection) {
736
+ this.isLocal = false;
737
+ this.loadData();
738
+ }
739
+ }
740
+ },
741
+ methods: {
742
+ loadData() {
743
+ this.mixinDatacomGet()
744
+ .then((res) => {
745
+ this.mixinDatacomResData = res.result.data;
746
+ if (this.mixinDatacomResData.length === 0) {
747
+ this.isLocal = false;
748
+ this.mixinDatacomErrorMessage = this.emptyText;
749
+ } else {
750
+ this.isLocal = true;
751
+ }
752
+ })
753
+ .catch((err) => {
754
+ this.mixinDatacomErrorMessage = err.message;
755
+ });
756
+ },
757
+ /**
758
+ * 获取父元素实例
759
+ */
760
+ getForm(name = 'uniForms') {
761
+ let parent = this.$parent;
762
+ let parentName = parent.$options.name;
763
+ while (parentName !== name) {
764
+ parent = parent.$parent;
765
+ if (!parent) return false;
766
+ parentName = parent.$options.name;
767
+ }
768
+ return parent;
769
+ },
770
+ chagne(e) {
771
+ const values = e.detail.value;
772
+ let detail = {
773
+ value: [],
774
+ data: []
775
+ };
776
+ if (this.multiple) {
777
+ this.range.forEach((item) => {
778
+ if (values.includes(item[this.map.value] + '')) {
779
+ detail.value.push(item[this.map.value]);
780
+ detail.data.push(item);
781
+ }
782
+ });
783
+ } else {
784
+ const range = this.range.find((item) => item[this.map.value] + '' === values);
785
+ if (range) {
786
+ detail = {
787
+ value: range[this.map.value],
788
+ data: range
789
+ };
790
+ }
791
+ }
792
+ // this.formItem && this.formItem.setValue(detail.value)
793
+ // TODO 兼容 vue2
794
+ this.$emit('input', detail.value);
795
+ // // TOTO 兼容 vue3
796
+ this.$emit('update:modelValue', detail.value);
797
+ this.$emit('change', {
798
+ detail
799
+ });
800
+ if (this.multiple) {
801
+ // 如果 v-model 没有绑定 ,则走内部逻辑
802
+ // if (this.value.length === 0) {
803
+ this.dataList = this.getDataList(detail.value, true);
804
+ // }
805
+ } else {
806
+ this.dataList = this.getDataList(detail.value);
807
+ }
808
+ },
809
+ /**
810
+ * 获取渲染的新数组
811
+ * @param {Object} value 选中内容
812
+ */
813
+ getDataList(value) {
814
+ // 解除引用关系,破坏原引用关系,避免污染源数据
815
+ let dataList = JSON.parse(JSON.stringify(this.range));
816
+ let list = [];
817
+ if (this.multiple) {
818
+ if (!Array.isArray(value)) {
819
+ value = [];
820
+ }
821
+ }
822
+ dataList.forEach((item, index) => {
823
+ item.disabled = item.disable || item.disabled || false;
824
+ if (this.multiple) {
825
+ if (value.length > 0) {
826
+ let have = value.find((val) => val === item[this.map.value]);
827
+ item.selected = have !== undefined;
828
+ } else {
829
+ item.selected = false;
830
+ }
831
+ } else {
832
+ item.selected = value === item[this.map.value];
833
+ }
834
+ list.push(item);
835
+ });
836
+ return this.setRange(list);
837
+ },
838
+ /**
839
+ * 处理最大最小值
840
+ * @param {Object} list
841
+ */
842
+ setRange(list) {
843
+ let selectList = list.filter((item) => item.selected);
844
+ let min = Number(this.min) || 0;
845
+ let max = Number(this.max) || '';
846
+ list.forEach((item, index) => {
847
+ if (this.multiple) {
848
+ if (selectList.length <= min) {
849
+ let have = selectList.find((val) => val[this.map.value] === item[this.map.value]);
850
+ if (have !== undefined) {
851
+ item.disabled = true;
852
+ }
853
+ }
854
+ if (selectList.length >= max && max !== '') {
855
+ let have = selectList.find((val) => val[this.map.value] === item[this.map.value]);
856
+ if (have === undefined) {
857
+ item.disabled = true;
858
+ }
859
+ }
860
+ }
861
+ this.setStyles(item, index);
862
+ list[index] = item;
863
+ });
864
+ return list;
865
+ },
866
+ /**
867
+ * 设置 class
868
+ * @param {Object} item
869
+ * @param {Object} index
870
+ */
871
+ setStyles(item, index) {
872
+ // 设置自定义样式
873
+ item.styleBackgroud = this.setStyleBackgroud(item);
874
+ item.styleIcon = this.setStyleIcon(item);
875
+ item.styleIconText = this.setStyleIconText(item);
876
+ item.styleRightIcon = this.setStyleRightIcon(item);
877
+ },
878
+ /**
879
+ * 获取选中值
880
+ * @param {Object} range
881
+ */
882
+ getSelectedValue(range) {
883
+ if (!this.multiple) return this.dataValue;
884
+ let selectedArr = [];
885
+ range.forEach((item) => {
886
+ if (item.selected) {
887
+ selectedArr.push(item[this.map.value]);
888
+ }
889
+ });
890
+ return this.dataValue.length > 0 ? this.dataValue : selectedArr;
891
+ },
892
+ /**
893
+ * 设置背景样式
894
+ */
895
+ setStyleBackgroud(item) {
896
+ let styles = {};
897
+ let selectedColor = this.selectedColor ? this.selectedColor : '#2979ff';
898
+ if (this.selectedColor) {
899
+ if (this.mode !== 'list') {
900
+ styles['border-color'] = item.selected ? selectedColor : '#DCDFE6';
901
+ }
902
+ if (this.mode === 'tag') {
903
+ styles['background-color'] = item.selected ? selectedColor : '#f5f5f5';
904
+ }
905
+ }
906
+ let classles = '';
907
+ for (let i in styles) {
908
+ classles += `${i}:${styles[i]};`;
909
+ }
910
+ return classles;
911
+ },
912
+ setStyleIcon(item) {
913
+ let styles = {};
914
+ let classles = '';
915
+ if (this.selectedColor) {
916
+ let selectedColor = this.selectedColor ? this.selectedColor : '#2979ff';
917
+ styles['background-color'] = item.selected ? selectedColor : '#fff';
918
+ styles['border-color'] = item.selected ? selectedColor : '#DCDFE6';
919
+ if (!item.selected && item.disabled) {
920
+ styles['background-color'] = '#F2F6FC';
921
+ styles['border-color'] = item.selected ? selectedColor : '#DCDFE6';
922
+ }
923
+ }
924
+ for (let i in styles) {
925
+ classles += `${i}:${styles[i]};`;
926
+ }
927
+ return classles;
928
+ },
929
+ setStyleIconText(item) {
930
+ let styles = {};
931
+ let classles = '';
932
+ if (this.selectedColor) {
933
+ let selectedColor = this.selectedColor ? this.selectedColor : '#2979ff';
934
+ if (this.mode === 'tag') {
935
+ styles.color = item.selected ? (this.selectedTextColor ? this.selectedTextColor : '#fff') : '#666';
936
+ } else {
937
+ styles.color = item.selected ? (this.selectedTextColor ? this.selectedTextColor : selectedColor) : '#666';
938
+ }
939
+ if (!item.selected && item.disabled) {
940
+ styles.color = '#999';
941
+ }
942
+ }
943
+ for (let i in styles) {
944
+ classles += `${i}:${styles[i]};`;
945
+ }
946
+ return classles;
947
+ },
948
+ setStyleRightIcon(item) {
949
+ let styles = {};
950
+ let classles = '';
951
+ if (this.mode === 'list') {
952
+ styles['border-color'] = item.selected ? this.styles.selectedColor : '#DCDFE6';
953
+ }
954
+ for (let i in styles) {
955
+ classles += `${i}:${styles[i]};`;
956
+ }
957
+ return classles;
958
+ }
959
+ }
960
+ };
961
+ </script>
962
+ <style>
963
+ @import 'style.css';
964
+ </style>