| <template> | 
|   <view class="tn-checkbox-class tn-checkbox" :style="[checkboxStyle]"> | 
|     <view | 
|       class="tn-checkbox__icon-wrap" | 
|       :class="[iconClass]" | 
|       :style="[iconStyle]" | 
|       @tap="toggle" | 
|     > | 
|       <view class="tn-checkbox__icon-wrap__icon" :class="[`tn-icon-${iconName}`]"></view> | 
|     </view> | 
|      | 
|     <view | 
|       class="tn-checkbox__label" | 
|       :class="[labelClass]" | 
|       :style="{ | 
|         fontSize: labelSize ? labelSize + 'rpx' : '' | 
|       }" | 
|       @tap="onClickLabel" | 
|     > | 
|       <slot></slot> | 
|     </view> | 
|   </view> | 
| </template> | 
|   | 
| <script> | 
|   export default { | 
|     name: 'tn-checkbox', | 
|     props: { | 
|       // checkbox名称 | 
|       name: { | 
|         type: [String, Number], | 
|         default: '' | 
|       }, | 
|       // 是否为选中状态 | 
|       value: { | 
|         type: Boolean, | 
|         default: false | 
|       }, | 
|       // 禁用选择 | 
|       disabled: { | 
|         type: Boolean, | 
|         default: false | 
|       }, | 
|       // 禁用点击标签进行选择 | 
|       disabledLabel: { | 
|         type: Boolean, | 
|         default: false | 
|       }, | 
|       // 选择框的形状 square 方形 circle 圆形 | 
|       shape: { | 
|         type: String, | 
|         default: '' | 
|       }, | 
|       // 选中时的颜色 | 
|       activeColor: { | 
|         type: String, | 
|         default: '' | 
|       }, | 
|       // 组件大小 | 
|       size: { | 
|         type: Number, | 
|         default: 0 | 
|       }, | 
|       // 图标名称 | 
|       iconName: { | 
|         type: String, | 
|         default: 'success' | 
|       }, | 
|       // 图标大小 | 
|       iconSize: { | 
|         type: Number, | 
|         default: 0 | 
|       }, | 
|       // label的字体大小 | 
|       labelSize: { | 
|         type: Number, | 
|         default: 0 | 
|       } | 
|     }, | 
|     computed: { | 
|       // 是否禁用选中,父组件的禁用会覆盖当前的禁用状态 | 
|       isDisabled() { | 
|         return this.disabled ? this.disabled : (this.parent ? this.parentData.disabled : false) | 
|       }, | 
|       // 是否禁用点击label选中,父组件的禁用会覆盖当前的禁用状态 | 
|       isDisabledLabel() { | 
|         return this.disabledLabel ? this.disabledLabel : (this.parent ? this.parentData.disabledLabel : false) | 
|       }, | 
|       // 尺寸 | 
|       checkboxSize() { | 
|         return this.size ? this.size : (this.parent ? this.parentData.size : 34) | 
|       }, | 
|       // 激活时的颜色 | 
|       elAvtiveColor() { | 
|         return this.activeColor ? this.activeColor : (this.parent ? this.parentData.activeColor : '#01BEFF') | 
|       }, | 
|       // 形状 | 
|       elShape() { | 
|         return this.shape ? this.shape : (this.parent ? this.parentData.shape : 'square') | 
|       }, | 
|       iconClass() { | 
|         let clazz = '' | 
|         clazz += (' tn-checkbox__icon-wrap--' + this.elShape) | 
|          | 
|         if (this.checkValue) clazz += ' tn-checkbox__icon-wrap--checked' | 
|         if (this.isDisabled) clazz += ' tn-checkbox__icon-wrap--disabled' | 
|         if (this.value && this.isDisabled) clazz += ' tn-checkbox__icon-wrap--disabled--checked' | 
|          | 
|         return clazz | 
|       }, | 
|       iconStyle() { | 
|         let style = {} | 
|         // 判断是否用户手动禁用和传递的值 | 
|         if (this.elAvtiveColor && this.checkValue && !this.isDisabled) { | 
|           style.borderColor = this.elAvtiveColor | 
|           style.backgroundColor = this.elAvtiveColor | 
|         } | 
|          | 
|         // checkbox内部的勾选图标,如果选中状态,为白色,否则为透明色即可 | 
|         style.color = this.checkValue ? '#FFFFFF' : 'transparent' | 
|          | 
|         style.width = this.checkboxSize + 'rpx' | 
|         style.height = style.width | 
|          | 
|         style.fontSize = (this.iconSize ? this.iconSize : (this.parent ? this.parentData.iconSize : 20)) + 'rpx' | 
|          | 
|         return style | 
|       }, | 
|       checkboxStyle() { | 
|         let style = {} | 
|         if (this.parent && this.parentData.width) { | 
|           // #ifdef MP | 
|           // 各家小程序因为它们特殊的编译结构,使用float布局 | 
|           style.float = 'left'; | 
|           // #endif | 
|           // #ifndef MP | 
|           // H5和APP使用flex布局 | 
|           style.flex = `0 0 ${this.parentData.width}`; | 
|           // #endif | 
|         } | 
|         if(this.parent && this.parentData.wrap) { | 
|             style.width = '100%'; | 
|             // #ifndef MP | 
|             // H5和APP使用flex布局,将宽度设置100%,即可自动换行 | 
|             style.flex = '0 0 100%'; | 
|             // #endif | 
|         } | 
|          | 
|         return style | 
|       }, | 
|       labelClass() { | 
|         let clazz = '' | 
|         if (this.isDisabled) { | 
|           clazz += ' tn-checkbox__label--disabled' | 
|         } | 
|         return clazz | 
|       } | 
|     }, | 
|     data() { | 
|       return { | 
|         // 当前checkbox的value值 | 
|         checkValue: false, | 
|         parentData: { | 
|           value: null, | 
|           max: null, | 
|           disabled: null, | 
|           disabledLabel: null, | 
|           shape: null, | 
|           activeColor: null, | 
|           size: null, | 
|           width: null, | 
|           wrap: null, | 
|           iconSize: null | 
|         } | 
|       } | 
|     }, | 
|     watch: { | 
|       value(val) { | 
|         this.checkValue = val | 
|       } | 
|     }, | 
|     created() { | 
|       // 支付宝小程序不支持provide/inject,所以使用这个方法获取整个父组件,在created定义,避免循环应用 | 
|       // this.parent = this.$t.$parent.call(this, 'tn-checkbox-group') | 
|       // // 如果存在u-checkbox-group,将本组件的this塞进父组件的children中 | 
|       // this.parent && this.parent.children.push(this) | 
|       // // 初始化父组件的value值 | 
|       // this.parent && this.parent.emitEvent() | 
|       this.updateParentData() | 
|       this.parent && this.parent.children.push(this) | 
|     }, | 
|     methods: { | 
|       updateCheckValue() { | 
|         // 更新当前checkbox的选中状态 | 
|         this.checkValue = (this.parent && this.parentData.value.includes(this.name)) || this.value === true | 
|         if (this.parent) { | 
|           if (this.value && !this.parentData.value.includes(this.name)) { | 
|             this.parentData.value.push(this.name) | 
|             this.parent.initValue(this.parentData.value) | 
|           } | 
|         } | 
|       }, | 
|       updateParentData() { | 
|         this.getParentData('tn-checkbox-group') | 
|         this.updateCheckValue() | 
|       }, | 
|       onClickLabel() { | 
|         if (!this.isDisabled && !this.isDisabledLabel) { | 
|           this.setValue() | 
|         } | 
|       }, | 
|       toggle() { | 
|         if (!this.isDisabled) { | 
|           this.setValue() | 
|         } | 
|       }, | 
|       emitEvent() { | 
|         this.$emit('change', { | 
|           name: this.name, | 
|           value: !this.checkValue | 
|         }) | 
|         if (this.parent) { | 
|           this.checkValue = !this.checkValue | 
|           // 执行父组件tn-checkbox-group的事件方法 | 
|           // 等待下一个周期再执行,因为this.$emit('input')作用于父组件,再反馈到子组件内部,需要时间 | 
|           setTimeout(() => { | 
|             if(this.parent.emitEvent) this.parent.emitEvent(); | 
|           }, 80) | 
|         } | 
|       }, | 
|       // 设置input的值,通过v-modal绑定组件的值 | 
|       setValue() { | 
|         // 判断是否为可选项组 | 
|         if (this.parent) { | 
|           // 反转状态 | 
|           if (this.checkValue === true) { | 
|             this.emitEvent() | 
|             // this.$emit('input', !this.checkValue) | 
|           } else { | 
|             // 超出最大可选项,弹出提示 | 
|             if (this.parentData.value.length >= this.parentData.max) { | 
|               return this.$t.message.toast(`最多可选${this.parent.max}项`) | 
|             } | 
|             // 如果原来为未选中状态,需要选中的数量少于父组件中设置的max值,才可以选中 | 
|             this.emitEvent(); | 
|             // this.$emit('input', !this.checkValue); | 
|           } | 
|         } else { | 
|           // 只有一个可选项 | 
|           this.emitEvent() | 
|           this.$emit('input', !this.checkValue) | 
|         } | 
|       } | 
|     } | 
|   } | 
| </script> | 
|   | 
| <style lang="scss" scoped> | 
|    | 
|   .tn-checkbox { | 
|     /* #ifndef APP-NVUE */ | 
|     display: inline-flex; | 
|     /* #endif */ | 
|     align-items: center; | 
|     overflow: hidden; | 
|     user-select: none; | 
|     line-height: 1.8; | 
|      | 
|     &__icon-wrap { | 
|       color: $tn-font-color; | 
|       flex: none; | 
|       display: flex; | 
|       flex-direction: row; | 
|       align-items: center; | 
|       justify-content: center; | 
|       box-sizing: border-box; | 
|       width: 42rpx; | 
|       height: 42rpx; | 
|       color: transparent; | 
|       text-align: center; | 
|       transition-property: color, border-color, background-color; | 
|       border: 1px solid $tn-font-sub-color; | 
|       transition-duration: 0.2s; | 
|        | 
|       /* #ifdef MP-TOUTIAO */ | 
|       // 头条小程序兼容性问题,需要设置行高为0,否则图标偏下 | 
|       &__icon { | 
|           line-height: 0; | 
|       } | 
|       /* #endif */ | 
|        | 
|       &--circle { | 
|         border-radius: 100%; | 
|       } | 
|        | 
|       &--square { | 
|         border-radius: 6rpx; | 
|       } | 
|        | 
|       &--checked { | 
|         color: #FFFFFF; | 
|         background-color: $tn-main-color; | 
|         border-color: $tn-main-color; | 
|       } | 
|        | 
|       &--disabled { | 
|         background-color: $tn-font-holder-color; | 
|         border-color: $tn-font-sub-color; | 
|       } | 
|        | 
|       &--disabled--checked { | 
|         color: $tn-font-sub-color !important; | 
|       } | 
|     } | 
|      | 
|     &__label { | 
|       word-wrap: break-word; | 
|       margin-left: 10rpx; | 
|       margin-right: 24rpx; | 
|       color: $tn-font-color; | 
|       font-size: 30rpx; | 
|        | 
|       &--disabled { | 
|         color: $tn-font-sub-color; | 
|       } | 
|     } | 
|   } | 
| </style> |