|
1 | 1 | <template> |
2 | | - <view class="uni-data-checklist"> |
| 2 | + <view class="uni-data-checklist" :style="{'margin-top':isTop+'px'}"> |
3 | 3 | <template v-if="!isLocal"> |
4 | 4 | <view class="uni-data-loading"> |
5 | 5 | <uni-load-more v-if="!mixinDatacomErrorMessage" status="loading" iconType="snow" :iconSize="18" :content-text="contentText"></uni-load-more> |
|
8 | 8 | </template> |
9 | 9 | <template v-else> |
10 | 10 | <checkbox-group v-if="multiple" class="checklist-group" :class="{'is-list':mode==='list' || wrap}" @change="chagne"> |
11 | | - <!-- :class="item.labelClass" --> |
12 | 11 | <label class="checklist-box" :class="['is--'+mode,item.selected?'is-checked':'',(disabled || !!item.disabled)?'is-disable':'',index!==0&&mode==='list'?'is-list-border':'']" :style="item.styleBackgroud" v-for="(item,index) in dataList" :key="index"> |
13 | | - <checkbox class="hidden" hidden :disabled="disabled || !!item.disabled" :value="item.value+''" :checked="item.selected" /> |
14 | | - <!-- :style="item.styleIcon" --> |
15 | | - |
| 12 | + <checkbox class="hidden" hidden :disabled="disabled || !!item.disabled" :value="item[map.value]+''" :checked="item.selected" /> |
16 | 13 | <view v-if="(mode !=='tag' && mode !== 'list') || ( mode === 'list' && icon === 'left')" class="checkbox__inner" :style="item.styleIcon"> |
17 | | - <!-- :class="item.checkboxClass" --> |
18 | 14 | <view class="checkbox__inner-icon"></view> |
19 | 15 | </view> |
20 | 16 | <view class="checklist-content" :class="{'list-content':mode === 'list' && icon ==='left'}"> |
21 | | - <!-- :class="item.textClass" --> |
22 | | - <text class="checklist-text" :style="item.styleIconText">{{item.text}}</text> |
23 | | - <!-- :class="item.listClass" --> |
| 17 | + <text class="checklist-text" :style="item.styleIconText">{{item[map.text]}}</text> |
24 | 18 | <view v-if="mode === 'list' && icon === 'right'" class="checkobx__list" :style="item.styleBackgroud"></view> |
25 | 19 | </view> |
26 | 20 | </label> |
27 | 21 | </checkbox-group> |
28 | 22 | <radio-group v-else class="checklist-group" :class="{'is-list':mode==='list','is-wrap':wrap}" @change="chagne"> |
29 | 23 | <!-- --> |
30 | 24 | <label class="checklist-box" :class="['is--'+mode,item.selected?'is-checked':'',(disabled || !!item.disabled)?'is-disable':'',index!==0&&mode==='list'?'is-list-border':'']" :style="item.styleBackgroud" v-for="(item,index) in dataList" :key="index"> |
31 | | - <radio class="hidden" hidden :disabled="disabled || item.disabled" :value="item.value+''" :checked="item.selected" /> |
32 | | - <!-- :class="item.checkboxBgClass" --> |
| 25 | + <radio class="hidden" hidden :disabled="disabled || item.disabled" :value="item[map.value]+''" :checked="item.selected" /> |
33 | 26 | <view v-if="(mode !=='tag' && mode !== 'list') || ( mode === 'list' && icon === 'left')" class="radio__inner" :style="item.styleBackgroud"> |
34 | | - <!-- :class="item.checkboxClass" --> |
35 | 27 | <view class="radio__inner-icon" :style="item.styleIcon"></view> |
36 | 28 | </view> |
37 | 29 | <view class="checklist-content" :class="{'list-content':mode === 'list' && icon ==='left'}"> |
38 | | - <!-- :class="item.textClass" --> |
39 | | - <text class="checklist-text" :style="item.styleIconText">{{item.text}}</text> |
40 | | - <!-- :class="item.listClass" --> |
| 30 | + <text class="checklist-text" :style="item.styleIconText">{{item[map.text]}}</text> |
41 | 31 | <view v-if="mode === 'list' && icon === 'right'" :style="item.styleRightIcon" class="checkobx__list"></view> |
42 | 32 | </view> |
43 | 33 | </label> |
|
48 | 38 |
|
49 | 39 | <script> |
50 | 40 | /** |
51 | | - * DataCheckbox 数据选择器 |
| 41 | + * DataChecklist 数据选择器 |
52 | 42 | * @description 通过数据渲染 checkbox 和 radio |
53 | | - * @tutorial https://ext.dcloud.net.cn/plugin?id=3456 |
| 43 | + * @tutorial https://ext.dcloud.net.cn/plugin?id=xxx |
54 | 44 | * @property {String} mode = [default| list | button | tag] 显示模式 |
55 | 45 | * @value default 默认横排模式 |
56 | 46 | * @value list 列表模式 |
|
66 | 56 | * @property {Boolean} selectedColor 选中颜色 |
67 | 57 | * @property {Boolean} emptyText 没有数据时显示的文字 ,本地数据无效 |
68 | 58 | * @property {Boolean} selectedTextColor 选中文本颜色,如不填写则自动显示 |
| 59 | + * @property {Object} map 字段映射, 默认 map={text:'text',value:'value'} |
69 | 60 | * @value left 左侧显示 |
70 | 61 | * @value right 右侧显示 |
71 | 62 | * @event {Function} change 选中发生变化触发 |
72 | 63 | */ |
73 | 64 |
|
| 65 | + // import clientdb from './clientdb.js' |
74 | 66 | export default { |
75 | | - name: 'uniDataCheckbox', |
| 67 | + name: 'uniDataChecklist', |
| 68 | + // mixins: [clientdb], |
76 | 69 | mixins: [uniCloud.mixinDatacom || {}], |
| 70 | + // model: { |
| 71 | + // prop: 'modelValue', |
| 72 | + // event: 'update:modelValue' |
| 73 | + // }, |
| 74 | + emits: ['input', 'update:modelValue', 'change'], |
77 | 75 | props: { |
78 | 76 | mode: { |
79 | 77 | type: String, |
80 | 78 | default: 'default' |
81 | 79 | }, |
| 80 | +
|
82 | 81 | multiple: { |
83 | 82 | type: Boolean, |
84 | 83 | default: false |
|
89 | 88 | return '' |
90 | 89 | } |
91 | 90 | }, |
| 91 | + // TODO vue3 |
| 92 | + modelValue: { |
| 93 | + type: [Array, String, Number], |
| 94 | + default () { |
| 95 | + return ''; |
| 96 | + } |
| 97 | + }, |
92 | 98 | localdata: { |
93 | 99 | type: Array, |
94 | 100 | default () { |
|
113 | 119 | }, |
114 | 120 | selectedColor: { |
115 | 121 | type: String, |
116 | | - default: '#007aff' |
| 122 | + default: '' |
117 | 123 | }, |
118 | 124 | selectedTextColor: { |
119 | 125 | type: String, |
120 | | - default: '#333' |
| 126 | + default: '' |
121 | 127 | }, |
122 | 128 | emptyText: { |
123 | 129 | type: String, |
|
126 | 132 | disabled: { |
127 | 133 | type: Boolean, |
128 | 134 | default: false |
| 135 | + }, |
| 136 | + map: { |
| 137 | + type: Object, |
| 138 | + default () { |
| 139 | + return { |
| 140 | + text: 'text', |
| 141 | + value: 'value' |
| 142 | + } |
| 143 | + } |
129 | 144 | } |
130 | 145 | }, |
131 | 146 | watch: { |
|
143 | 158 | value(newVal) { |
144 | 159 | this.dataList = this.getDataList(newVal) |
145 | 160 | this.formItem && this.formItem.setValue(newVal) |
| 161 | + }, |
| 162 | + modelValue(newVal) { |
| 163 | + this.dataList = this.getDataList(newVal); |
| 164 | + this.formItem && this.formItem.setValue(newVal); |
146 | 165 | } |
147 | 166 | }, |
148 | 167 | data() { |
|
158 | 177 | styles: { |
159 | 178 | selectedColor: '#007aff', |
160 | 179 | selectedTextColor: '#333', |
161 | | - } |
| 180 | + }, |
| 181 | + isTop: 0 |
162 | 182 | }; |
163 | 183 | }, |
| 184 | + computed: { |
| 185 | + dataValue() { |
| 186 | + if (this.value === '') return this.modelValue |
| 187 | + if (this.modelValue === '') return this.value |
| 188 | + return this.value |
| 189 | + } |
| 190 | + }, |
164 | 191 | created() { |
165 | 192 | this.form = this.getForm('uniForms') |
166 | 193 | this.formItem = this.getForm('uniFormsItem') |
167 | | - this.formItem && this.formItem.setValue(this.value) |
| 194 | + // this.formItem && this.formItem.setValue(this.value) |
168 | 195 |
|
169 | 196 | if (this.formItem) { |
| 197 | + this.isTop = 6 |
170 | 198 | if (this.formItem.name) { |
171 | 199 | this.rename = this.formItem.name |
172 | 200 | this.form.inputChildrens.push(this) |
|
221 | 249 |
|
222 | 250 | if (this.multiple) { |
223 | 251 | this.range.forEach(item => { |
224 | | - if (values.includes(item.value + '')) { |
225 | | - detail.value.push(item.value) |
| 252 | +
|
| 253 | + if (values.includes(item[this.map.value] + '')) { |
| 254 | + detail.value.push(item[this.map.value]) |
226 | 255 | detail.data.push(item) |
227 | 256 | } |
228 | 257 | }) |
229 | 258 | } else { |
230 | | - const range = this.range.find(item => (item.value + '') === values) |
| 259 | + const range = this.range.find(item => (item[this.map.value] + '') === values) |
231 | 260 | if (range) { |
232 | 261 | detail = { |
233 | | - value: range.value, |
| 262 | + value: range[this.map.value], |
234 | 263 | data: range |
235 | 264 | } |
236 | 265 | } |
237 | 266 | } |
238 | 267 | this.formItem && this.formItem.setValue(detail.value) |
239 | | - this.$emit('input', detail.value) |
| 268 | + // TODO 兼容 vue2 |
| 269 | + this.$emit('input', detail.value); |
| 270 | + // // TOTO 兼容 vue3 |
| 271 | + this.$emit('update:modelValue', detail.value); |
240 | 272 | this.$emit('change', { |
241 | 273 | detail |
242 | 274 | }) |
|
267 | 299 | item.disabled = item.disable || item.disabled || false |
268 | 300 | if (this.multiple) { |
269 | 301 | if (value.length > 0) { |
270 | | - let have = value.find(val => val === item.value) |
| 302 | + let have = value.find(val => val === item[this.map.value]) |
271 | 303 | item.selected = have !== undefined |
272 | 304 | } else { |
273 | 305 | item.selected = false |
274 | 306 | } |
275 | 307 | } else { |
276 | | - item.selected = value === item.value |
| 308 | + item.selected = value === item[this.map.value] |
277 | 309 | } |
278 | 310 |
|
279 | 311 | list.push(item) |
|
291 | 323 | list.forEach((item, index) => { |
292 | 324 | if (this.multiple) { |
293 | 325 | if (selectList.length <= min) { |
294 | | - let have = selectList.find(val => val.value === item.value) |
| 326 | + let have = selectList.find(val => val[this.map.value] === item[this.map.value]) |
295 | 327 | if (have !== undefined) { |
296 | 328 | item.disabled = true |
297 | 329 | } |
298 | 330 | } |
299 | 331 |
|
300 | 332 | if (selectList.length >= max && max !== '') { |
301 | | - let have = selectList.find(val => val.value === item.value) |
| 333 | + let have = selectList.find(val => val[this.map.value] === item[this.map.value]) |
302 | 334 | if (have === undefined) { |
303 | 335 | item.disabled = true |
304 | 336 | } |
|
320 | 352 | item.styleIcon = this.setStyleIcon(item) |
321 | 353 | item.styleIconText = this.setStyleIconText(item) |
322 | 354 | item.styleRightIcon = this.setStyleRightIcon(item) |
323 | | -
|
324 | 355 | }, |
325 | 356 |
|
326 | 357 | /** |
327 | 358 | * 获取选中值 |
328 | 359 | * @param {Object} range |
329 | 360 | */ |
330 | 361 | getSelectedValue(range) { |
331 | | - if (!this.multiple) return this.value |
| 362 | + if (!this.multiple) return this.dataValue |
332 | 363 | let selectedArr = [] |
333 | 364 | range.forEach((item) => { |
334 | 365 | if (item.selected) { |
335 | | - selectedArr.push(item.value) |
| 366 | + selectedArr.push(item[this.map.value]) |
336 | 367 | } |
337 | 368 | }) |
338 | | - return this.value.length > 0 ? this.value : selectedArr |
| 369 | + return this.dataValue.length > 0 ? this.dataValue : selectedArr |
339 | 370 | }, |
340 | 371 |
|
341 | 372 | /** |
342 | 373 | * 设置背景样式 |
343 | 374 | */ |
344 | 375 | setStyleBackgroud(item) { |
345 | 376 | let styles = {} |
346 | | - // if (item.selected) { |
| 377 | + let selectedColor = this.selectedColor ? this.selectedColor : '#007aff' |
347 | 378 | if (this.mode !== 'list') { |
348 | | - styles['border-color'] = item.selected ? this.selectedColor : '#DCDFE6' |
| 379 | + styles['border-color'] = item.selected ? selectedColor : '#DCDFE6' |
349 | 380 | } |
350 | 381 | if (this.mode === 'tag') { |
351 | | - styles['background-color'] = item.selected ? this.selectedColor : '#f5f5f5' |
| 382 | + styles['background-color'] = item.selected ? selectedColor : '#f5f5f5' |
352 | 383 | } |
353 | | - // } |
354 | 384 | let classles = '' |
355 | 385 | for (let i in styles) { |
356 | 386 | classles += `${i}:${styles[i]};` |
|
360 | 390 | setStyleIcon(item) { |
361 | 391 | let styles = {} |
362 | 392 | let classles = '' |
363 | | - // if (item.selected) { |
364 | | - styles['background-color'] = item.selected ? this.selectedColor : '#fff' |
365 | | - styles['border-color'] = item.selected ? this.selectedColor : '#DCDFE6' |
| 393 | + let selectedColor = this.selectedColor ? this.selectedColor : '#007aff' |
| 394 | + styles['background-color'] = item.selected ? selectedColor : '#fff' |
| 395 | + styles['border-color'] = item.selected ? selectedColor : '#DCDFE6' |
366 | 396 |
|
367 | 397 | if (!item.selected && item.disabled) { |
368 | 398 | styles['background-color'] = '#F2F6FC' |
369 | | - styles['border-color'] = item.selected ? this.selectedColor : '#DCDFE6' |
| 399 | + styles['border-color'] = item.selected ? selectedColor : '#DCDFE6' |
370 | 400 | } |
371 | 401 |
|
372 | 402 | for (let i in styles) { |
373 | 403 | classles += `${i}:${styles[i]};` |
374 | 404 | } |
375 | | - // } |
376 | 405 | return classles |
377 | 406 | }, |
378 | 407 | setStyleIconText(item) { |
379 | 408 | let styles = {} |
380 | 409 | let classles = '' |
381 | | - // if (item.selected) { |
382 | | - // if (this.selectedTextColor) { |
383 | | - // styles.color = item.selected?this.selectedTextColor:'#999' |
384 | | - // } else { |
| 410 | + let selectedColor = this.selectedColor ? this.selectedColor : '#007aff' |
385 | 411 | if (this.mode === 'tag') { |
386 | | - styles.color = item.selected ? '#fff' : '#333' |
387 | | -
|
| 412 | + styles.color = item.selected ? (this.selectedTextColor ? this.selectedTextColor : '#fff') : '#333' |
388 | 413 | } else { |
389 | | - styles.color = item.selected ? this.selectedColor : '#333' |
| 414 | + styles.color = item.selected ? (this.selectedTextColor ? this.selectedTextColor : selectedColor) : '#333' |
390 | 415 | } |
391 | 416 | if (!item.selected && item.disabled) { |
392 | 417 | styles.color = '#999' |
393 | 418 | } |
394 | | - // } |
| 419 | +
|
395 | 420 | for (let i in styles) { |
396 | 421 | classles += `${i}:${styles[i]};` |
397 | 422 | } |
398 | | - // } |
399 | | -
|
400 | 423 | return classles |
401 | 424 | }, |
402 | 425 | setStyleRightIcon(item) { |
403 | 426 | let styles = {} |
404 | 427 | let classles = '' |
405 | | - // if (item.selected) { |
406 | 428 | if (this.mode === 'list') { |
407 | 429 | styles['border-color'] = item.selected ? this.styles.selectedColor : '#DCDFE6' |
408 | 430 | } |
409 | 431 | for (let i in styles) { |
410 | 432 | classles += `${i}:${styles[i]};` |
411 | 433 | } |
412 | | - // } |
413 | 434 |
|
414 | 435 | return classles |
415 | 436 | } |
416 | | - // setColor(){ |
417 | | - // return |
418 | | - // } |
419 | 437 | } |
420 | 438 | } |
421 | 439 | </script> |
|
484 | 502 | } |
485 | 503 |
|
486 | 504 | .uni-data-checklist .checklist-group .checklist-box .checklist-content .checkobx__list { |
487 | | - border: 1px solid #fff; |
488 | | - border-left: 0; |
489 | | - border-top: 0; |
| 505 | + border-right-width: 1px; |
| 506 | + border-right-color: #007aff; |
| 507 | + border-right-style: solid; |
| 508 | + border-bottom-width: 1px; |
| 509 | + border-bottom-color: #007aff; |
| 510 | + border-bottom-style: solid; |
490 | 511 | height: 12px; |
491 | 512 | width: 6px; |
| 513 | + left: -5px; |
492 | 514 | transform-origin: center; |
493 | 515 | transform: rotate(45deg); |
494 | 516 | opacity: 0; |
|
519 | 541 | left: 5px; |
520 | 542 | height: 8px; |
521 | 543 | width: 4px; |
522 | | - border: 1px solid #fff; |
523 | | - border-left: 0; |
524 | | - border-top: 0; |
| 544 | + border-right-width: 1px; |
| 545 | + border-right-color: #fff; |
| 546 | + border-right-style: solid; |
| 547 | + border-bottom-width: 1px; |
| 548 | + border-bottom-color: #fff; |
| 549 | + border-bottom-style: solid; |
525 | 550 | opacity: 0; |
526 | 551 | transform-origin: center; |
527 | 552 | transform: rotate(40deg); |
|
607 | 632 | opacity: 0.4; |
608 | 633 | } |
609 | 634 |
|
| 635 | + .uni-data-checklist .checklist-group .checklist-box.is--default.is-checked.is-disable .radio__inner { |
| 636 | + opacity: 0.4; |
| 637 | + } |
| 638 | +
|
610 | 639 | .uni-data-checklist .checklist-group .checklist-box.is--button { |
611 | 640 | margin-right: 10px; |
612 | 641 | padding: 5px 15px; |
|
0 commit comments