CNCEC_APP/uni_modules/uview-pro/components/u-badge/u-badge.vue

154 lines
4.6 KiB
Vue
Raw Normal View History

2026-03-25 14:54:15 +08:00
<template>
<view
v-if="show"
class="u-badge"
:class="[
isDot ? 'u-badge-dot' : '',
size === 'mini' ? 'u-badge-mini' : '',
type ? 'u-badge--bg--' + type : '',
customClass
]"
:style="
$u.toStyle(
{
top: (offset as number[])[0] + 'rpx',
right: (offset as number[])[1] + 'rpx',
fontSize: fontSize + 'rpx',
position: absolute ? 'absolute' : 'static',
color: color,
backgroundColor: bgColor
},
boxStyle,
customStyle
)
"
>
{{ showText }}
</view>
</template>
<script lang="ts">
export default {
name: 'u-badge',
options: {
addGlobalClass: true,
// #ifndef MP-TOUTIAO
virtualHost: true,
// #endif
styleIsolation: 'shared'
}
};
</script>
<script setup lang="ts">
import { computed } from 'vue';
import { BadgeProps } from './types';
import { $u } from '../..';
/**
* badge 角标
* @description 本组件一般用于展示头像的地方如个人中心或者评论列表页的用户头像展示等场所
* @tutorial https://uviewpro.cn/zh/components/badge.html
* @property {String|Number} count 展示的数字大于 overflowCount 时显示为 ${overflowCount}+为0且show-zero为false时隐藏
* @property {Boolean} is-dot 不展示数字只有一个小点默认false
* @property {Boolean} absolute 组件是否绝对定位为true时offset参数才有效默认true
* @property {String|Number} overflow-count 展示封顶的数字值默认99
* @property {String} type 使用预设的背景颜色默认error
* @property {Boolean} show-zero 当数值为 0 是否展示 Badge默认false
* @property {String} size Badge的尺寸设为mini会得到小一号的Badge默认default
* @property {Array} offset 设置badge的位置偏移格式为 [x, y]也即设置的为top和right的值单位rpxabsolute为true时有效默认[20, 20]
* @property {String} color 字体颜色默认var(--u-white-color)
* @property {String} bgColor 背景颜色优先级比type高如设置type参数会失效
* @property {Boolean} is-center 组件中心点是否和父组件右上角重合优先级比offset高如设置offset参数会失效默认false
* @example <u-badge type="error" count="7"></u-badge>
*/
const props = defineProps(BadgeProps);
/**
* 计算 badge 的定位和变换样式
*/
const boxStyle = computed(() => {
let style: Record<string, any> = {};
if (props.isCenter) {
style.top = 0;
style.right = 0;
// Y轴-50%意味着badge向上移动了badge自身高度一半X轴50%,意味着向右移动了自身宽度一半
style.transform = 'translateY(-50%) translateX(50%)';
} else {
style.top = (props.offset as number[])[0] + 'rpx';
style.right = (props.offset as number[])[1] + 'rpx';
style.transform = 'translateY(0) translateX(0)';
}
// 如果尺寸为mini后接上scale()
if (props.size === 'mini') {
style.transform = style.transform + ' scale(0.8)';
}
return style;
});
/**
* 计算显示的文本内容
*/
const showText = computed(() => {
if (props.isDot) return '';
else {
if (Number(props.count) > props.overflowCount) return `${props.overflowCount}+`;
else return props.count;
}
});
/**
* 是否显示组件
*/
const show = computed(() => {
// 如果count的值为0并且showZero设置为false不显示组件
if (Number(props.count) === 0 && props.showZero === false) return false;
else return true;
});
</script>
<style lang="scss" scoped>
@import '../../libs/css/style.components.scss';
.u-badge {
/* #ifndef APP-NVUE */
display: inline-flex;
/* #endif */
justify-content: center;
align-items: center;
line-height: 24rpx;
padding: 4rpx 8rpx;
border-radius: 100rpx;
z-index: 9;
&--bg--primary {
background-color: $u-type-primary;
}
&--bg--error {
background-color: $u-type-error;
}
&--bg--success {
background-color: $u-type-success;
}
&--bg--info {
background-color: $u-type-info;
}
&--bg--warning {
background-color: $u-type-warning;
}
}
.u-badge-dot {
height: 16rpx;
width: 16rpx;
border-radius: 100rpx;
line-height: 1;
}
.u-badge-mini {
transform: scale(0.8);
transform-origin: center center;
}
</style>