PrimeVue Badge 组件完全指南:从 value/severity/size 属性到 Design Tokens 主题定制
【免费下载链接】primevueNext Generation Vue UI Component Library项目地址: https://gitcode.com/GitHub_Trending/pr/primevue
Badge(徽章)是 PrimeVue 中用于在其他元素上叠加小型状态指示的组件,常用于角标数字、状态点、按钮未读计数等场景。本文基于 PrimeVue 仓库内置的 Badge 组件文档(badge.md),完整覆盖其导入方式、无障碍处理、基础用法、Button 内建徽章、OverlayBadge 覆盖式徽章、severity 与 size 属性,并逐一给出 Props、PassThrough 选项与 Design Tokens 全量表;同时结合 packages/primevue/src/badge 下的源码实现,解释data-p修饰符、类名映射和 OverlayBadge 复用机制的底层原理,帮助你既能直接落地使用,也能在自定义主题或 passthrough 定制时有的放矢。
安装与导入
Badge 家族包含两个组件:Badge(行内徽章)与OverlayBadge(覆盖式徽章),从primevue包按需导入即可:
// import as component import Badge from 'primevue/badge'; import OverlayBadge from 'primevue/overlaybadge';对应仓库中的源码入口分别为 Badge.vue 和 OverlayBadge.vue。
无障碍(Accessibility)
官方文档明确了 Badge 的无障碍策略,理解它对屏幕阅读器集成很重要:
- Screen Reader:Badge 默认不带任何 ARIA 角色与属性;由于组件开启了属性透传(
inheritAttrs: false+ 绑定到根元素),你可以直接给根元素附加aria-*角色和属性。对于动态变化的徽章内容,可配合aria-live让读屏器播报更新。 - Keyboard Support:组件内部不含任何可交互元素,因此没有内建键盘处理;如果徽章本身需要获得焦点(例如作为可点击状态指示器),可自行添加
tabindex并实现自定义键盘事件处理。
从源码看,BaseBadge.vue 继承自@primevue/core/basecomponent,所有未声明的 HTML 属性都会落在根元素上,这正是「任意属性透传」说法的底层依据。
Basic:value 属性与默认插槽
徽章显示的内容由value属性或默认插槽(default slot)决定,二者等价:
<Badge value="2"></Badge> <Badge>10</Badge>源码层面,Badge.vue 的模板仅是一个根span:
<span :class="cx('root')" :data-p="dataP" v-bind="ptmi('root')"> <slot>{{ value }}</slot> </span>即默认插槽未提供内容时回退渲染value。props.value在 BaseBadge.vue 中声明为String | Number类型、默认null。
一个值得注意的细节是data-p属性的生成逻辑(Badge.vue):
- 当
value非空且长度为 1(例如"2"、"9")时,标记为circle(圆形徽章); - 当
value为空且没有默认插槽时,标记为empty(渲染为纯圆点 dot); severity与size的值也会原样写入data-p,供 CSS 选择器命中。
单元测试 验证了value="29"+severity="warn"+size="large"时,根元素带有.p-badge.p-component、.p-badge-warn与.p-badge-lg类。
Button:按钮内建徽章支持
Button 组件内建了对徽章的支持,无需手动叠加,直接传badge属性即可在按钮内联渲染角标;badgeSeverity控制其严重级别,还可以搭配variant="outlined"等按钮样式:
<Button type="button" label="Notifications" icon="pi pi-bell" badge="2" /> <Button type="button" label="Inbox" icon="pi pi-inbox" badge="2" badgeSeverity="contrast" variant="outlined" />Composition API 完整示例:
<template> <div class="card flex justify-center flex-wrap gap-4"> <Button type="button" label="Notifications" icon="pi pi-bell" badge="2" /> <Button type="button" label="Inbox" icon="pi pi-inbox" badge="2" badgeSeverity="contrast" variant="outlined" /> </div> </template> <script setup> </script>从源码看这条内建链路是如何工作的:
- BaseButton.vue 声明了三个相关 props:
badge(String,默认null)、badgeClass(附加到徽章的类)、badgeSeverity(String,默认值"secondary",可选值与 Badge 的 severity 一致); - Button.vue 的模板中条件渲染了一个真实 Badge 实例,并透传
unstyled与父组件的ptm('pcBadge')passthrough,因此 Button 的全局pt配置可以精确作用到其内部徽章节点:
<Badge v-if="badge" :value="badge" :class="badgeClass" :severity="badgeSeverity" :unstyled="unstyled" :pt="ptm('pcBadge')"></Badge>也就是说,按钮上的徽章就是标准Badge组件,badgeClass可自由覆盖样式,而按钮pt配置中的pcBadge键专门控制这个内嵌徽章。
Overlay:用 OverlayBadge 给任意元素加角标
OverlayBadge通过包裹任意内容,在其上以覆盖定位方式显示一个徽章:
<OverlayBadge value="2"> <i class="pi pi-bell" style="font-size: 2rem" /> </OverlayBadge> <OverlayBadge value="4" severity="danger"> <i class="pi pi-calendar" style="font-size: 2rem" /> </OverlayBadge> <OverlayBadge severity="danger"> <i class="pi pi-envelope" style="font-size: 2rem" /> </OverlayBadge>Composition API 完整示例:
<template> <div class="card flex flex-wrap justify-center gap-6"> <OverlayBadge value="2"> <i class="pi pi-bell" style="font-size: 2rem" /> </OverlayBadge> <OverlayBadge value="4" severity="danger"> <i class="pi pi-calendar" style="font-size: 2rem" /> </OverlayBadge> <OverlayBadge severity="danger"> <i class="pi pi-envelope" style="font-size: 2rem" /> </OverlayBadge> </div> </template> <script setup> </script>注意第三个示例只传了severity而没传value——结合上文data-p的empty判定逻辑,它会渲染为一个纯状态圆点(dot),而不是空数字徽章。
源码上,OverlayBadge.vue 的实现非常薄:根div渲染默认插槽,然后把v-bind="$props"原样转发给内部的Badge子组件。这意味着OverlayBadge接受value、severity、size等全部 Badge props(继承自 BaseOverlayBadge.vue),并且可以通过pt的pcBadge键单独定制内部徽章节点。其根类名由 OverlayBadgeStyle.js 固定为p-overlaybadge。
Severity:严重级别变体
severity决定徽章的视觉变体,可选值共 7 种:不传(primary 默认样式)、secondary、success、info、warn、danger、contrast:
<Badge value="2"></Badge> <Badge value="6" severity="secondary"></Badge> <Badge value="8" severity="success"></Badge> <Badge value="4" severity="info"></Badge> <Badge value="9" severity="warn"></Badge> <Badge value="3" severity="danger"></Badge> <Badge value="5" severity="contrast"></Badge>Composition API 完整示例:
<template> <div class="card flex flex-wrap justify-center gap-2"> <Badge value="2"></Badge> <Badge value="6" severity="secondary"></Badge> <Badge value="8" severity="success"></Badge> <Badge value="4" severity="info"></Badge> <Badge value="9" severity="warn"></Badge> <Badge value="3" severity="danger"></Badge> <Badge value="5" severity="contrast"></Badge> </div> </template> <script setup> </script>在 BadgeStyle.js 中,每个 severity 值被一一映射为根元素上的独立类名:p-badge-info、p-badge-success、p-badge-warn、p-badge-danger、p-badge-secondary、p-badge-contrast。因此这些类名可以直接用作自定义 CSS 的选择器,与下文 Design Tokens 的变量配合使用。
Size:尺寸定制
size属性用于调整徽章尺寸,合法取值为small、large、xlarge(不传为默认尺寸):
<Badge value="8" size="xlarge" severity="success"></Badge> <Badge value="6" size="large" severity="warn"></Badge> <Badge value="4" severity="info"></Badge> <Badge value="2" size="small"></Badge>Composition API 完整示例:
<template> <div class="card flex flex-wrap justify-center items-end gap-2"> <Badge value="8" size="xlarge" severity="success"></Badge> <Badge value="6" size="large" severity="warn"></Badge> <Badge value="4" severity="info"></Badge> <Badge value="2" size="small"></Badge> </div> </template> <script setup> </script>尺寸到类名的映射同样在 BadgeStyle.js 中完成:small → p-badge-sm、large → p-badge-lg、xlarge → p-badge-xl。对应的尺寸变量见下文--p-badge-sm-*、--p-badge-lg-*、--p-badge-xl-*系列 Design Tokens。
Props 全量表
Badge组件的完整 props(类型定义见 Badge.d.ts):
| 名称 | 类型 | 默认值 | 说明 |
|---|---|---|---|
value | string \| number | - | 徽章内显示的数值/文本 |
severity | null \| HintedString<"secondary" \| "info" \| "success" \| "warn" \| "danger" \| "contrast"> | - | 徽章的严重级别变体 |
size | null \| HintedString<"small" \| "large" \| "xlarge"> | - | 徽章尺寸,可选small、large、xlarge |
dt | any | - | 使用 Design Tokens 生成组件作用域的 CSS 变量 |
pt | PassThrough<BadgePassThroughOptions<any>> | - | 向组件内部 DOM 元素透传属性 |
ptOptions | any | - | 配置 passthrough(pt)的行为选项 |
unstyled | boolean | false | 开启后移除组件在 core 中附带的基础样式 |
补充说明:
dt是「组件级 design token」入口,传入 token 对象即可为当前实例生成作用域 CSS 变量,优先级高于全局主题变量;ptOptions可控制pt的合并/覆盖策略(如是否允许属性覆盖),属于 PrimeVue 通用的 passthrough 体系配置;unstyled: true会剥离组件自带核心样式,适合完全自绘风格的场景,Button 内建徽章也会把自身的unstyled透传给内部 Badge(见 Button.vue)。
Pass Through(pt)选项
pt允许向组件内部 DOM 元素透传任意 HTML 属性或类名,Badge 支持的透传点如下:
| 名称 | 类型 | 说明 |
|---|---|---|
root | BadgePassThroughOptionType<T> | 向根元素透传属性 |
hooks | any | 管理所有生命周期钩子(如rootOnMounted等) |
root的取值可以是属性对象、字符串类名,或返回前两者的函数(函数可接收instance、props、global、parent上下文,见 Badge.d.ts 中BadgePassThroughMethodOptions定义)。模板中通过ptmi('root')绑定到根span,因此root中传入的tabindex、aria-live等属性可直接实现上文无障碍章节提到的自定义键盘/读屏支持。
Theming:CSS 类名
| 类名 | 说明 |
|---|---|
p-badge | 根元素类名 |
实际渲染中根元素还会附加p-component以及上述各变体类(p-badge-circle、p-badge-dot、p-badge-sm/lg/xl、p-badge-{severity},见 BadgeStyle.js),OverlayBadge 根元素则为p-overlaybadge。这些类名均可用于自定义样式选择器。
Theming:Design Tokens(设计令牌)
Badge 的视觉参数全部由--p-badge-*系列 CSS 变量驱动,可在主题层统一覆盖:
| Token | CSS 变量 | 说明 |
|---|---|---|
badge.border.radius | --p-badge-border-radius | 根元素圆角 |
badge.padding | --p-badge-padding | 根元素内边距 |
badge.font.size | --p-badge-font-size | 根元素字号 |
badge.font.weight | --p-badge-font-weight | 根元素字重 |
badge.min.width | --p-badge-min-width | 根元素最小宽度 |
badge.height | --p-badge-height | 根元素高度 |
badge.dot.size | --p-badge-dot-size | 圆点(dot)尺寸 |
badge.sm.font.size | --p-badge-sm-font-size | small 尺寸字号 |
badge.sm.min.width | --p-badge-sm-min-width | small 尺寸最小宽度 |
badge.sm.height | --p-badge-sm-height | small 尺寸高度 |
badge.lg.font.size | --p-badge-lg-font-size | large 尺寸字号 |
badge.lg.min.width | --p-badge-lg-min-width | large 尺寸最小宽度 |
badge.lg.height | --p-badge-lg-height | large 尺寸高度 |
badge.xl.font.size | --p-badge-xl-font-size | xlarge 尺寸字号 |
badge.xl.min.width | --p-badge-xl-min-width | xlarge 尺寸最小宽度 |
badge.xl.height | --p-badge-xl-height | xlarge 尺寸高度 |
badge.primary.background | --p-badge-primary-background | primary 背景色 |
badge.primary.color | --p-badge-primary-color | primary 文字色 |
badge.secondary.background | --p-badge-secondary-background | secondary 背景色 |
badge.secondary.color | --p-badge-secondary-color | secondary 文字色 |
badge.success.background | --p-badge-success-background | success 背景色 |
badge.success.color | --p-badge-success-color | success 文字色 |
badge.info.background | --p-badge-info-background | info 背景色 |
badge.info.color | --p-badge-info-color | info 文字色 |
badge.warn.background | --p-badge-warn-background | warn 背景色 |
badge.warn.color | --p-badge-warn-color | warn 文字色 |
badge.danger.background | --p-badge-danger-background | danger 背景色 |
badge.danger.color | --p-badge-danger-color | danger 文字色 |
badge.contrast.background | --p-badge-contrast-background | contrast 背景色 |
badge.contrast.color | --p-badge-contrast-color | contrast 文字色 |
从源码结构看,BadgeStyle.js 通过BaseStyle.extend({ name: 'badge', style, classes })注册了组件样式:classes负责按 props 动态拼接类名,style则来自@primeuix/styles/badge包,其中的 CSS 规则统一引用上述--p-badge-*变量。因此定制主题时的推荐路径是:在主题 SCSS/全局样式中覆盖变量(如--p-badge-danger-background),而不是重写类名规则;单实例微调则使用dtprop 生成组件作用域变量,二者的作用域范围不同。
小结
Badge 的 API 面很收敛,但扩展点设计完整:内容用value/默认插槽,变体用severity,尺寸用size,叠加定位交给OverlayBadge,按钮场景走badge/badgeSeverity内建链路;样式定制则分层为全局 Design Tokens(主题级)、dt(实例级)和pt(属性/钩子级)。掌握这套分层后,无论是做未读计数、状态圆点还是完全自绘的角标,都能在 packages/primevue/src/badge 与 packages/primevue/src/overlaybadge 的源码中找到确切的行为依据。
【免费下载链接】primevueNext Generation Vue UI Component Library项目地址: https://gitcode.com/GitHub_Trending/pr/primevue
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考