| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268 | <template>	<view class="uni-badge--x">		<slot />		<text v-if="text" :class="classNames" :style="[badgeWidth, 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']			},			badgeWidth() {				return {					width: `${this.width}px`				}			},			dotStyle() {				if (!this.isDot) return {}				return {					width: '10px',					height: '10px',					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;		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-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>
 |