Element Plus Badge 徽标组件完全指南:从基础用法到源码级原理
【免费下载链接】element-plus🎉 A Vue.js 3 UI Library made by Element team项目地址: https://gitcode.com/GitHub_Trending/el/element-plus
Badge(徽标)是 Element Plus(Vue 3 UI 组件库)中用于在按钮、图标等元素右上角展示数字、状态标记的轻量级组件,典型场景包括"未读消息数""购物车数量""版本更新提示"等。本文以官方文档 docs/en-US/component/badge.md 为核心,结合组件源码、主题样式与单元测试,系统讲解 Badge 的全部 API、使用技巧与底层渲染机制,读完即可在生产项目中熟练驾驭数字徽标、自定义内容、红点与偏移定位等能力。
基础用法:用 value 展示数字或文本
Badge 最核心的能力是通过value属性展示徽标内容,value同时接受number与string两种类型:传入数字时显示数值,传入字符串时原样渲染文本。当组件包裹了默认插槽内容(如按钮)时,徽标会自动定位在右上角。
<template> <el-badge :value="12" class="item"> <el-button>comments</el-button> </el-badge> <el-badge :value="3" class="item"> <el-button>replies</el-button> </el-badge> <el-badge :value="1" class="item" type="primary"> <el-button>comments</el-button> </el-badge> <el-badge :value="2" class="item" type="warning"> <el-button>replies</el-button> </el-badge> <el-badge :value="1" class="item" color="green"> <el-button>custom background</el-button> </el-badge> </template>该示例对应官方演示 docs/examples/badge/basic.vue,展示了三种典型形态:独立数字徽标、通过type切换语义色、通过color自定义背景色。
从源码看,value的声明位于 packages/components/badge/src/badge.ts,其类型为[String, Number],默认值为'':
value: { type: [String, Number], default: '', },而徽标最终显示内容由 packages/components/badge/src/badge.vue 中的content计算属性决定:
const content = computed<string>(() => { if (props.isDot) return '' if (isNumber(props.value) && isNumber(props.max)) { return props.max < props.value ? `${props.max}+` : `${props.value}` } return `${props.value}` })值得注意的细节:当value与max均为数字时走"封顶"分支;只要二者之一不是数字(例如字符串),就直接用字符串模板输出value,这正是"字符串值可显示自定义文本"的原理。单元测试 packages/components/badge/tests/badge.test.tsx 验证了value={80}时渲染文本为'80'。
最大值封顶:max 的显示规则
当消息数量过大(如 200 条未读)时,UI 上通常需要压缩为"99+"的形式。通过max属性可以自定义封顶阈值:当value超过max时,徽标显示为{max}+。
<template> <el-badge :value="200" :max="99" class="item"> <el-button>comments</el-button> </el-badge> <el-badge :value="100" :max="10" class="item"> <el-button>replies</el-button> </el-badge> </template>该示例对应官方演示 docs/examples/badge/max.vue:200 > 99显示99+,100 > 10显示10+。
必须注意:max 仅对数字生效
max的默认值是99(见 badge.ts),且只在value是数字时生效。这是由content计算属性中的isNumber(props.value) && isNumber(props.max)双重判断保证的——如果value传的是字符串(如"new"),max会被完全忽略。
测试用例 badge.test.tsx 对max的动态变化做了覆盖:value从 200 变为 80 时,显示内容从'100+'变为'80',证明该计算是响应式的。
自定义内容:字符串 value 与 content 插槽
除了数字,Badge 还支持完全自定义的展示内容,有两种途径:
1. 直接传入字符串
value传字符串时,徽标直接显示该文本,适合"new""hot"等场景:
<el-badge value="new" class="item"> <el-button>comments</el-button> </el-badge> <el-badge value="hot" class="item"> <el-button>replies</el-button> </el-badge>2. 使用 content 插槽(2.9.1+)
从 2.9.1 版本起,官方提供content具名插槽,插槽作用域暴露{ value: string }(即最终计算出的徽标文本),让你能自由组合图标、文字甚至任意模板结构:
<el-badge value="99" class="item"> <el-button>share</el-button> <template #content="{ value }"> <div class="custom-content"> <el-icon> <Message /> </el-icon> <span>{{ value }}</span> </div> </template> </el-badge>上述示例来自官方演示 docs/examples/badge/customize.vue,在徽标内渲染了"图标 + 数字"的组合。对应的渲染实现见 badge.vue:
<slot name="content" :value="content"> {{ content }} </slot>即:提供content插槽时优先渲染插槽内容,否则回退到{{ content }}文本输出。测试用例 badge.test.tsx 验证了 content 插槽可渲染自定义节点。
提示:
default插槽用于包裹宿主元素(如按钮),content插槽用于定制徽标本身,二者分工不同。
红点模式:is-dot
当只需"有更新"的弱提示、不需要具体数字时,可使用红点模式。设置is-dot属性后,徽标渲染为一个 8×8 像素的圆点,数字内容被忽略:
<el-badge is-dot class="item">query</el-badge> <el-badge is-dot class="item"> <el-button class="share-button" :icon="Share" type="primary" /> </el-badge>该示例来自官方演示 docs/examples/badge/dot.vue。红点的视觉定义位于 packages/theme-chalk/src/badge.scss:
@include when(dot) { height: 8px; width: 8px; padding: 0; right: 0; border-radius: 50%; }is-dot的声明为Boolean类型(见 badge.ts),默认false。源码中content计算属性对isDot有短路处理——为true时直接返回空字符串,确保红点模式下不渲染任何文本。
偏移定位:offset(2.7.0+)
从 2.7.0 版本开始,Badge 支持通过offset属性微调徽标相对默认位置的偏移量。其格式为[left, top]的二元数组,分别表示相对默认位置向右(left)和向下(top)的偏移:
<el-badge class="item" :value="1" :offset="[10, 5]"> <el-button>offset</el-button> </el-badge>示例来自官方演示 docs/examples/badge/offset.vue。offset默认值为[0, 0](见 badge.ts)。
偏移的底层实现原理
从源码 badge.vue 可以看出,offset并不是直接移动元素,而是通过负margin-right与正margin-top实现:
const style = computed<StyleValue>(() => { return [ { backgroundColor: props.color, marginRight: addUnit(-props.offset[0]), marginTop: addUnit(props.offset[1]), }, props.badgeStyle ?? {}, ] })addUnit来自@element-plus/utils,负责为数值自动追加单位。由于徽标默认固定在右上角(见下方"固定定位"分析),向右移动对应减小margin-right(因此取负值),向下移动对应增加margin-top。测试 badge.test.tsx 精确断言了offset={[10, 10]}时生成的样式为margin-right: -10px与margin-top: 10px。
隐藏、零值控制与自定义颜色
除官方演示覆盖的能力外,badge.md的 API 表还列出了三个高频属性,这里结合源码补充说明。
hidden:完全隐藏徽标
hidden为Boolean,默认false。它并非通过 CSS 隐藏,而是直接从 DOM 树中移除<sup>元素——见 badge.vue 的v-if="!hidden && (content || isDot || $slots.content)"条件。测试用例 badge.test.tsx 验证了hidden切换时元素的存在与消失。
show-zero:是否显示零值(2.6.0+)
show-zero默认true,即value为 0 时仍显示"0"。设为false后,零值徽标会被添加is-hide-zero类,由样式 badge.scss 的display: none隐藏:
@include when(hide-zero) { display: none; }注意一个边界行为(见 badge.test.tsx):若同时设置了负数max(如max={-1})且value为 0,由于max < value,显示内容会变成-1+而非 0,此时show-zero不再生效——因为显示的文本本身已非 "0"。
color:自定义背景色(2.6.3+)
color为String类型,直接作为内联background-color注入(见 badge.vue),优先级高于type决定的主题色。测试 badge.test.tsx 验证了color="blue"会生成background-color: blue样式。
API 参考
Attributes
| 名称 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| value | 显示值 | string/number | '' |
| max | 最大值,超出后显示{max}+,仅在 value 为数字时生效 | number | 99 |
| is-dot | 是否显示为小圆点 | boolean | false |
| hidden | 是否隐藏徽标 | boolean | false |
| type | 徽标类型 | 'primary' \| 'success' \| 'warning' \| 'danger' \| 'info' | danger |
| show-zero ^(2.6.0) | value 为 0 时是否显示徽标 | boolean | true |
| color ^(2.6.3) | 圆点背景色 | string | — |
| offset ^(2.7.0) | 徽标偏移量 | [number, number] | [0, 0] |
| badge-style ^(2.7.1) | 徽标自定义样式 | CSSProperties | — |
| badge-class ^(2.7.1) | 徽标自定义类名 | string | — |
以上参数均可在 packages/components/badge/src/badge.ts 的badgeProps中找到完整声明与默认值定义。
Slots
| 名称 | 说明 | 类型 |
|---|---|---|
| default | 自定义默认内容(宿主元素) | — |
| content ^(2.9.1) | 自定义徽标内容 | { value: string } |
通过 ref 访问实例
Badge 通过defineExpose暴露了content计算属性(见 badge.vue),对应的实例类型BadgeInstance定义在 packages/components/badge/src/instance.ts,可在需要程序化读取当前徽标文本时使用。
渲染机制与样式体系解析
组件结构与 BEM 命名
Badge 的模板结构非常精简(badge.vue):外层div.el-badge包裹默认插槽,内层<sup>渲染徽标,并整体包在el-zoom-in-center过渡动画中。命名空间由useNamespace('badge')生成。
<transition :name="`${ns.namespace.value}-zoom-in-center`"> <sup v-if="!hidden && (content || isDot || $slots.content)" :class="[ ns.e('content'), ns.em('content', type), ns.is('fixed', !!$slots.default), ns.is('dot', isDot), ns.is('hide-zero', !showZero && value === 0), badgeClass, ]" :style="style" > <slot name="content" :value="content"> {{ content }} </slot> </sup> </transition>固定定位:is-fixed
从类名生成逻辑可以看出,只要提供了默认插槽(宿主元素),徽标就会获得is-fixed类,从而采用绝对定位固定在右上角。对应样式见 badge.scss:
@include when(fixed) { position: absolute; top: 0; right: calc(1px + #{getCssVar('badge', 'size')} / 2); transform: translateY(-50%) translateX(100%); z-index: getCssVar('index', 'normal'); }反之,若 Badge 单独使用(无默认插槽),则退化为普通内联元素,不会绝对定位。测试 badge.test.tsx 专门断言了带默认插槽时is-fixed类的存在。
类型色与 CSS 变量
type的五个取值(primary / success / warning / danger / info)通过 SCSS 循环生成对应背景色(badge.scss),颜色值取自$badge主题变量,并支持通过--el-badge-*CSS 变量进行主题定制。默认danger即红色系,这也是红点模式的默认底色来源。
注册与使用
在完整引入 Element Plus 时,ElBadge已随插件自动注册。若按需引入,可以从element-plus导入组件及其样式:
import { ElBadge } from 'element-plus' import 'element-plus/es/components/badge/style/css'组件的安装封装位于 packages/components/badge/index.ts,通过withInstall(Badge)提供全局注册能力;样式入口为 packages/components/badge/style/index.ts,引入后即可在模板中使用<el-badge>。
小结
Badge 是 Element Plus 中 API 面小但细节丰富的组件:value双类型决定了数字/文本两种形态,max封顶只在数字场景生效,content插槽(2.9.1+)提供了最大限度的自定义空间,offset(2.7.0+)通过负 margin 实现精确偏移,is-fixed/is-hide-zero/el-zoom-in-center等类名则展示了 BEM 命名与主题变量的典型实践。结合 badge.vue、badge.ts 与 badge.test.tsx 阅读源码,即可对徽标组件的渲染链路建立完整认知。
【免费下载链接】element-plus🎉 A Vue.js 3 UI Library made by Element team项目地址: https://gitcode.com/GitHub_Trending/el/element-plus
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考