<template>
<div class="b-badge">
<slot>
<b-button>默认</b-button>
</slot>
<transition name="b-zoom-in-center">
<sup
v-show="content || isDot || content === 0"
v-text="content"
:class="badgeClass"
>
</sup>
</transition>
</div>
</template>
<script lang="ts">
import { computed, defineComponent } from 'vue'
import BButton from '@/components/button/src/button.vue'
import type { badgeValue, badgeDot, badgeMax } from './interface'
import type { PropType } from 'vue'
export default defineComponent({
name: 'BBadge',
components: { BButton },
props: {
// 显示的数字
value: {
type: Number as PropType<badgeValue>,
default: 1
},
// 最大值
max: {
type: Number as PropType<badgeMax>,
default: 99
},
// 显示原点
isDot: {
type: Boolean as PropType<badgeDot>,
default: false
}
},
setup(props) {
const { isDot } = toRefs(props)
const content = computed(() => {
if (isDot.value) return ''
if (typeof props.value === 'number' && typeof props.max === 'number') {
return props.max < props.value ? `${props.max}+` : props.value
}
return props.value
})
const badgeClass = computed(() => [
props.isDot && 'b-badge-isdot',
!props.isDot && 'b-badge-content'
])
return {
content,
badgeClass
}
}
})
</script>
<style lang="less" scoped>
@import "../style/badge.less";
</style>
css部分:
.b-badge {
position: relative;
display: inline-block;
vertical-align: middle;
.b-badge-content {
position: absolute;
top: 0;
right: 12px;
display: inline-block;
min-width: 20px;
height: 20px;
padding: 0 4px;
font-size: 12px;
line-height: 20px;
color: @backgroundColor;
text-align: center;
white-space: nowrap;
background-color: @dangerColor;
border-radius: 10px;
transform: translateY(-50%) translateX(100%);
}
.b-badge-isdot {
position: absolute;
top: 0;
right: 12px;
right: 4px;
display: inline-block;
width: 8px;
height: 8px;
padding: 0;
background-color: @dangerColor;
border-radius: 50%;
transform: translateY(-50%) translateX(100%);
}
}
.b-zoom-in-center-enter-active,
.b-zoom-in-center-leave-active {
transition: all 0.3s cubic-bezier(0.55, 0, 0.1, 1);
}
.b-zoom-in-center-enter,
.b-zoom-in-center-leave-active {
opacity: 0;
transform: scaleX(0);
}