|
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