| <template> | 
|     <view class="uni-badge--x"> | 
|         <slot /> | 
|         <text v-if="text" :class="classNames" :style="[positionStyle, customStyle, dotStyle]" | 
|             class="uni-badge" @click="onClick()">{{displayValue}}</text> | 
|     </view> | 
| </template> | 
|   | 
| <script> | 
|     /** | 
|      * Badge 数字角标 | 
|      * @description 数字角标一般和其它控件(列表、9宫格等)配合使用,用于进行数量提示,默认为实心灰色背景 | 
|      * @tutorial https://ext.dcloud.net.cn/plugin?id=21 | 
|      * @property {String} text 角标内容 | 
|      * @property {String} size = [normal|small] 角标内容 | 
|      * @property {String} type = [info|primary|success|warning|error] 颜色类型 | 
|      *     @value info 灰色 | 
|      *     @value primary 蓝色 | 
|      *     @value success 绿色 | 
|      *     @value warning 黄色 | 
|      *     @value error 红色 | 
|      * @property {String} inverted = [true|false] 是否无需背景颜色 | 
|      * @property {Number} maxNum 展示封顶的数字值,超过 99 显示 99+ | 
|      * @property {String} absolute = [rightTop|rightBottom|leftBottom|leftTop] 开启绝对定位, 角标将定位到其包裹的标签的四角上         | 
|      *     @value rightTop 右上 | 
|      *     @value rightBottom 右下 | 
|      *     @value leftTop 左上 | 
|      *     @value leftBottom 左下 | 
|      * @property {Array[number]} offset    距定位角中心点的偏移量,只有存在 absolute 属性时有效,例如:[-10, -10] 表示向外偏移 10px,[10, 10] 表示向 absolute 指定的内偏移 10px | 
|      * @property {String} isDot = [true|false] 是否显示为一个小点 | 
|      * @event {Function} click 点击 Badge 触发事件 | 
|      * @example <uni-badge text="1"></uni-badge> | 
|      */ | 
|   | 
|     export default { | 
|         name: 'UniBadge', | 
|         emits: ['click'], | 
|         props: { | 
|             type: { | 
|                 type: String, | 
|                 default: 'error' | 
|             }, | 
|             inverted: { | 
|                 type: Boolean, | 
|                 default: false | 
|             }, | 
|             isDot: { | 
|                 type: Boolean, | 
|                 default: false | 
|             }, | 
|             maxNum: { | 
|                 type: Number, | 
|                 default: 99 | 
|             }, | 
|             absolute: { | 
|                 type: String, | 
|                 default: '' | 
|             }, | 
|             offset: { | 
|                 type: Array, | 
|                 default () { | 
|                     return [0, 0] | 
|                 } | 
|             }, | 
|             text: { | 
|                 type: [String, Number], | 
|                 default: '' | 
|             }, | 
|             size: { | 
|                 type: String, | 
|                 default: 'small' | 
|             }, | 
|             customStyle: { | 
|                 type: Object, | 
|                 default () { | 
|                     return {} | 
|                 } | 
|             } | 
|         }, | 
|         data() { | 
|             return {}; | 
|         }, | 
|         computed: { | 
|             width() { | 
|                 return String(this.text).length * 8 + 12 | 
|             }, | 
|             classNames() { | 
|                 const { | 
|                     inverted, | 
|                     type, | 
|                     size, | 
|                     absolute | 
|                 } = this | 
|                 return [ | 
|                     inverted ? 'uni-badge--' + type + '-inverted' : '', | 
|                     'uni-badge--' + type, | 
|                     'uni-badge--' + size, | 
|                     absolute ? 'uni-badge--absolute' : '' | 
|                 ].join(' ') | 
|             }, | 
|             positionStyle() { | 
|                 if (!this.absolute) return {} | 
|                 let w = this.width / 2, | 
|                     h = 10 | 
|                 if (this.isDot) { | 
|                     w = 5 | 
|                     h = 5 | 
|                 } | 
|                 const x = `${- w  + this.offset[0]}px` | 
|                 const y = `${- h + this.offset[1]}px` | 
|   | 
|                 const whiteList = { | 
|                     rightTop: { | 
|                         right: x, | 
|                         top: y | 
|                     }, | 
|                     rightBottom: { | 
|                         right: x, | 
|                         bottom: y | 
|                     }, | 
|                     leftBottom: { | 
|                         left: x, | 
|                         bottom: y | 
|                     }, | 
|                     leftTop: { | 
|                         left: x, | 
|                         top: y | 
|                     } | 
|                 } | 
|                 const match = whiteList[this.absolute] | 
|                 return match ? match : whiteList['rightTop'] | 
|             }, | 
|             dotStyle() { | 
|                 if (!this.isDot) return {} | 
|                 return { | 
|                     width: '10px', | 
|                     minWidth: '0', | 
|                     height: '10px', | 
|                     padding: '0', | 
|                     borderRadius: '10px' | 
|                 } | 
|             }, | 
|             displayValue() { | 
|                 const { | 
|                     isDot, | 
|                     text, | 
|                     maxNum | 
|                 } = this | 
|                 return isDot ? '' : (Number(text) > maxNum ? `${maxNum}+` : text) | 
|             } | 
|         }, | 
|         methods: { | 
|             onClick() { | 
|                 this.$emit('click'); | 
|             } | 
|         } | 
|     }; | 
| </script> | 
|   | 
| <style lang="scss" > | 
|     $uni-primary: #2979ff !default; | 
|     $uni-success: #4cd964 !default; | 
|     $uni-warning: #f0ad4e !default; | 
|     $uni-error: #dd524d !default; | 
|     $uni-info: #909399 !default; | 
|   | 
|   | 
|     $bage-size: 12px; | 
|     $bage-small: scale(0.8); | 
|   | 
|     .uni-badge--x { | 
|         /* #ifdef APP-NVUE */ | 
|         // align-self: flex-start; | 
|         /* #endif */ | 
|         /* #ifndef APP-NVUE */ | 
|         display: inline-block; | 
|         /* #endif */ | 
|         position: relative; | 
|     } | 
|   | 
|     .uni-badge--absolute { | 
|         position: absolute; | 
|     } | 
|   | 
|     .uni-badge--small { | 
|         transform: $bage-small; | 
|         transform-origin: center center; | 
|     } | 
|   | 
|     .uni-badge { | 
|         /* #ifndef APP-NVUE */ | 
|         display: flex; | 
|         overflow: hidden; | 
|         box-sizing: border-box; | 
|         /* #endif */ | 
|         justify-content: center; | 
|         flex-direction: row; | 
|         height: 20px; | 
|         min-width: 20px; | 
|         padding: 0 4px; | 
|         line-height: 18px; | 
|         color: #fff; | 
|         border-radius: 100px; | 
|         background-color: $uni-info; | 
|         background-color: transparent; | 
|         border: 1px solid #fff; | 
|         text-align: center; | 
|         font-family: 'Helvetica Neue', Helvetica, sans-serif; | 
|         font-feature-settings: "tnum"; | 
|         font-size: $bage-size; | 
|         /* #ifdef H5 */ | 
|         z-index: 999; | 
|         cursor: pointer; | 
|         /* #endif */ | 
|   | 
|         &--info { | 
|             color: #fff; | 
|             background-color: $uni-info; | 
|         } | 
|   | 
|         &--primary { | 
|             background-color: $uni-primary; | 
|         } | 
|   | 
|         &--success { | 
|             background-color: $uni-success; | 
|         } | 
|   | 
|         &--warning { | 
|             background-color: $uni-warning; | 
|         } | 
|   | 
|         &--error { | 
|             background-color: $uni-error; | 
|         } | 
|   | 
|         &--inverted { | 
|             padding: 0 5px 0 0; | 
|             color: $uni-info; | 
|         } | 
|   | 
|         &--info-inverted { | 
|             color: $uni-info; | 
|             background-color: transparent; | 
|         } | 
|   | 
|         &--primary-inverted { | 
|             color: $uni-primary; | 
|             background-color: transparent; | 
|         } | 
|   | 
|         &--success-inverted { | 
|             color: $uni-success; | 
|             background-color: transparent; | 
|         } | 
|   | 
|         &--warning-inverted { | 
|             color: $uni-warning; | 
|             background-color: transparent; | 
|         } | 
|   | 
|         &--error-inverted { | 
|             color: $uni-error; | 
|             background-color: transparent; | 
|         } | 
|   | 
|     } | 
| </style> |