<template>
<div class="el-badge">
<!-- 默认插槽,用于放置需要标记的元素(如按钮、图标等) -->
<slot></slot>
<transition name="el-zoom-in-center">
<sup
v-show="!hidden && (content || content === 0 || isDot)"
v-text="content"
class="el-badge__content"
:class="[
type ? 'el-badge__content--' + type : null,
{
'is-fixed': $slots.default,
'is-dot': isDot
}
]">
</sup>
</transition>
</div>
</template>
<script>
export default {
name: 'ElBadge',
props: {
// 标记显示的数值或文本
value: [String, Number],
// 最大值,超过此值时显示为 "max+"
max: Number,
// 是否显示为小圆点
isDot: Boolean,
// 是否隐藏标记
hidden: Boolean,
// 标记类型,决定颜色样式
type: {
type: String,
// 自定义验证器,只允许指定的类型值
validator(val) {
return ['primary', 'success', 'warning', 'info', 'danger'].indexOf(val) > -1;
}
}
},
computed: {
// 计算标记显示的内容
content() {
// 如果是小圆点模式,不显示内容
if (this.isDot) return;
const value = this.value;
const max = this.max;
// 如果 value 和 max 都是数字类型
if (typeof value === 'number' && typeof max === 'number') {
// 超过最大值时显示 "max+",否则显示实际值
return max < value ? `${max}+` : value;
}
// 直接返回 value(字符串或数字)
return value;
}
}
};
</script>
Badge 组件教学文档
组件概述
Badge 是一个标记组件,用于在按钮、图标等元素上显示数字标记或状态标记。常用于显示通知数量、未读消息数、状态指示等场景。该组件支持数字标记、小圆点标记、自定义颜色和最大值限制等功能。
一、模板部分(Template)
1.1 容器元素
<div class="el-badge">
作用:组件的根容器,使用 el-badge 类名作为基础样式。
说明:
- 包裹整个组件的内容
- 提供定位上下文
- 作为样式钩子
1.2 默认插槽
<slot></slot>
作用:放置需要标记的元素。
说明:
- 使用默认插槽,允许父组件传入任意内容
- 可以是按钮、图标、头像等任何元素
- 标记会相对于这个元素进行定位
使用示例:
<el-badge :value="12">
<el-button>消息</el-button>
</el-badge>
<el-badge :value="5">
<el-icon :size="20">
<bell />
</el-icon>
</el-badge>
1.3 过渡动画
<transition name="el-zoom-in-center">
作用:为标记添加缩放淡入动画效果。
原理:
- 使用 Vue 的内置过渡组件
el-zoom-in-center类名实现从中心缩放淡入的效果- 当标记的显示状态变化时,自动应用动画
动画效果:
- 显示时:从中心放大并淡入
- 隐藏时:缩小并淡出到中心
1.4 标记元素
<sup
v-show="!hidden && (content || content === 0 || isDot)"
v-text="content"
class="el-badge__content"
:class="[
type ? 'el-badge__content--' + type : null,
{
'is-fixed': $slots.default,
'is-dot': isDot
}
]">
</sup>
详细解析:
1.4.1 v-show 条件
v-show="!hidden && (content || content === 0 || isDot)"
作用:控制标记的显示/隐藏。
条件解析:
!hidden:未隐藏时才显示content:有内容时显示content === 0:内容为 0 时也显示(重要!)isDot:小圆点模式时显示
为什么需要 content === 0:
0在 JavaScript 中是 falsy 值- 如果只写
content,值为 0 时会被隐藏 - 但 0 是一个有效的数值,应该显示
示例:
<!-- 显示:value=12 -->
<el-badge :value="12"></el-badge>
<!-- 显示:value=0 -->
<el-badge :value="0"></el-badge>
<!-- 隐藏:value="" -->
<el-badge :value=""></el-badge>
<!-- 隐藏:hidden=true -->
<el-badge :value="5" :hidden="true"></el-badge>
1.4.2 v-text 指令
v-text="content"
作用:设置标记的文本内容。
说明:
- 使用计算属性
content的值 - 相比
{{ }}插值,v-text性能更好 - 避免 XSS 攻击(自动转义)
1.4.3 基础类名
class="el-badge__content"
作用:标记的基础样式类名。
样式包括:
- 背景色
- 文字颜色
- 圆角
- 内边距
- 字体大小
- 定位方式
1.4.4 动态类名
:class="[
type ? 'el-badge__content--' + type : null,
{
'is-fixed': $slots.default,
'is-dot': isDot
}
]"
类型类名:
type ? 'el-badge__content--' + type : null
作用:根据 type 属性添加对应的颜色类名。
可能的类名:
el-badge__content--primary:蓝色el-badge__content--success:绿色el-badge__content--warning:橙色el-badge__content--info:灰色el-badge__content--danger:红色
示例:
<el-badge :value="5" type="primary"></el-badge> <!-- 蓝色 -->
<el-badge :value="5" type="success"></el-badge> <!-- 绿色 -->
<el-badge :value="5" type="danger"></el-badge> <!-- 红色 -->
条件类名:
{
'is-fixed': $slots.default,
'is-dot': isDot
}
is-fixed 类:
- 条件:
$slots.default存在 - 作用:将标记固定在父元素的右上角
- 效果:绝对定位,相对于父元素
is-dot 类:
- 条件:
isDot为true - 作用:将标记显示为小圆点
- 效果:圆形,无文字,固定大小
二、脚本部分(Script)
2.1 组件定义
export default {
name: 'ElBadge',
作用:定义组件名称。
说明:
- 用于在 Vue DevTools 中识别组件
- 便于调试和开发
2.2 Props 属性
2.2.1 value
value: [String, Number]
作用:标记显示的数值或文本。
类型:
- 字符串:可以显示文本,如 "NEW"、"HOT"
- 数字:显示数字,如 12、99
使用示例:
<!-- 显示数字 -->
<el-badge :value="12">
<el-button>消息</el-button>
</el-badge>
<!-- 显示文本 -->
<el-badge value="NEW">
<el-button>新品</el-button>
</el-badge>
注意事项:
- 空字符串
""会隐藏标记 - 数字
0会显示标记 - 配合
max属性使用时,必须是数字类型
2.2.2 max
max: Number
作用:设置最大值,超过此值时显示为 "max+"。
说明:
- 类型:数字
- 可选属性
- 只有当
value也是数字类型时才生效
使用示例:
<!-- 显示:5 -->
<el-badge :value="5" :max="99"></el-badge>
<!-- 显示:99+ -->
<el-badge :value="120" :max="99"></el-badge>
<!-- 显示:999+ -->
<el-badge :value="1500" :max="999"></el-badge>
应用场景:
- 通知数量:超过 99 显示 "99+"
- 未读消息:超过 999 显示 "999+"
- 避免数字过大影响布局
2.2.3 isDot
isDot: Boolean
作用:是否显示为小圆点。
说明:
- 类型:布尔值
- 默认值:
false - 设置为
true时,标记显示为小圆点,不显示文字
使用示例:
<!-- 显示小圆点 -->
<el-badge is-dot>
<el-button>消息</el-button>
</el-badge>
<!-- 显示数字 -->
<el-badge :value="5">
<el-button>消息</el-button>
</el-badge>
应用场景:
- 状态指示:有新消息时显示红点
- 简洁设计:不需要显示具体数量
- 移动端:节省空间
注意事项:
isDot为true时,value和max属性会被忽略- 小圆点有固定的大小和样式
2.2.4 hidden
hidden: Boolean
作用:是否隐藏标记。
说明:
- 类型:布尔值
- 默认值:
false - 设置为
true时,完全隐藏标记
使用示例:
<!-- 隐藏标记 -->
<el-badge :value="5" :hidden="true">
<el-button>消息</el-button>
</el-badge>
<!-- 显示标记 -->
<el-badge :value="5" :hidden="false">
<el-button>消息</el-button>
</el-badge>
应用场景:
- 条件显示:根据业务逻辑控制
- 动态切换:用户可以关闭通知
- 临时隐藏:不需要显示时
注意事项:
- 即使
value有值,hidden为true也会隐藏 - 可以通过动态绑定
:hidden来控制显示状态
2.2.5 type
type: {
type: String,
validator(val) {
return ['primary', 'success', 'warning', 'info', 'danger'].indexOf(val) > -1;
}
}
作用:标记类型,决定颜色样式。
类型:字符串
可选值:
primary:蓝色(主要)success:绿色(成功)warning:橙色(警告)info:灰色(信息)danger:红色(危险)
验证器:
validator(val) {
return ['primary', 'success', 'warning', 'info', 'danger'].indexOf(val) > -1;
}
作用:
- 自定义属性验证器
- 确保只接受指定的类型值
- 如果传入无效值,Vue 会发出警告
使用示例:
<!-- 蓝色 -->
<el-badge :value="5" type="primary"></el-badge>
<!-- 绿色 -->
<el-badge :value="5" type="success"></el-badge>
<!-- 橙色 -->
<el-badge :value="5" type="warning"></el-badge>
<!-- 灰色 -->
<el-badge :value="5" type="info"></el-badge>
<!-- 红色 -->
<el-badge :value="5" type="danger"></el-badge>
应用场景:
danger:未读消息、错误提示success:成功数量、完成状态warning:警告数量、待处理info:信息数量、一般提示primary:主要信息、重要通知
为什么需要验证器:
- 防止传入无效的类型值
- 提供友好的错误提示
- 确保组件样式的一致性
2.3 Computed 计算属性
2.3.1 content
content() {
if (this.isDot) return;
const value = this.value;
const max = this.max;
if (typeof value === 'number' && typeof max === 'number') {
return max < value ? `${max}+` : value;
}
return value;
}
作用:计算标记显示的内容。
执行逻辑:
-
小圆点模式:
if (this.isDot) return;- 如果是小圆点模式,直接返回
undefined - 不显示任何文字内容
- 如果是小圆点模式,直接返回
-
获取属性值:
const value = this.value; const max = this.max; -
数字类型判断:
if (typeof value === 'number' && typeof max === 'number') { return max < value ? `${max}+` : value; }- 如果
value和max都是数字类型 - 判断是否超过最大值
- 超过:显示
"max+"(如"99+") - 未超过:显示实际值
- 如果
-
默认返回:
return value;- 直接返回
value - 可以是字符串或数字
- 直接返回
示例演示:
| value | max | isDot | 显示内容 |
|---|---|---|---|
| 5 | 99 | false | 5 |
| 120 | 99 | false | 99+ |
| 0 | 99 | false | 0 |
| "NEW" | 99 | false | NEW |
| 5 | - | false | 5 |
| 5 | 99 | true | (无内容) |
为什么需要计算属性:
- 封装复杂的显示逻辑
- 响应式更新:当
value、max、isDot变化时自动重新计算 - 提高代码复用性
- 使模板更简洁
性能优化:
- 计算属性有缓存
- 只有依赖项变化时才重新计算
- 避免不必要的重复计算
三、组件使用示例
3.1 基础用法
<template>
<div>
<el-badge :value="12">
<el-button>消息</el-button>
</el-badge>
<el-badge :value="3">
<el-button>评论</el-button>
</el-badge>
<el-badge :value="1">
<el-button>回复</el-button>
</el-badge>
</div>
</template>
说明:最简单的用法,在按钮右上角显示数字标记。
3.2 最大值
<template>
<div>
<el-badge :value="200" :max="99">
<el-button>消息</el-button>
</el-badge>
<el-badge :value="100" :max="10">
<el-button>回复</el-button>
</el-badge>
</div>
</template>
说明:超过最大值时显示 "max+"。
3.3 自定义内容
<template>
<div>
<el-badge value="NEW">
<el-button>新品</el-button>
</el-badge>
<el-badge value="HOT">
<el-button>热门</el-button>
</el-badge>
<el-badge value="SALE">
<el-button>促销</el-button>
</el-badge>
</div>
</template>
说明:使用字符串显示自定义文本。
3.4 小圆点
<template>
<div>
<el-badge is-dot>
<el-button>消息</el-button>
</el-badge>
<el-badge is-dot>
<el-icon :size="20">
<bell />
</el-icon>
</el-badge>
</div>
</template>
说明:显示小圆点,不显示数字。
3.5 不同类型
<template>
<div>
<el-badge :value="12" type="primary">
<el-button>主要</el-button>
</el-badge>
<el-badge :value="3" type="success">
<el-button>成功</el-button>
</el-badge>
<el-badge :value="5" type="warning">
<el-button>警告</el-button>
</el-badge>
<el-badge :value="8" type="info">
<el-button>信息</el-button>
</el-badge>
<el-badge :value="1" type="danger">
<el-button>危险</el-button>
</el-badge>
</div>
</template>
说明:使用不同的颜色类型。
3.6 隐藏标记
<template>
<div>
<el-badge :value="12" :hidden="true">
<el-button>消息</el-button>
</el-badge>
<el-badge :value="12" :hidden="showBadge">
<el-button>消息</el-button>
</el-badge>
</div>
</template>
<script>
export default {
data() {
return {
showBadge: false
}
}
}
</script>
说明:通过 hidden 属性控制标记的显示/隐藏。
3.7 配合图标使用
<template>
<div>
<el-badge :value="5">
<el-icon :size="24">
<bell />
</el-icon>
</el-badge>
<el-badge :value="3" is-dot>
<el-icon :size="24">
<message />
</el-icon>
</el-badge>
</div>
</template>
说明:在图标上显示标记。
3.8 配合头像使用
<template>
<div>
<el-badge :value="2" is-dot>
<el-avatar :size="40" src="user.jpg"></el-avatar>
</el-badge>
</div>
</template>
说明:在头像上显示状态标记。
3.9 动态更新
<template>
<div>
<el-badge :value="messageCount" :max="99">
<el-button @click="addMessage">消息</el-button>
</el-badge>
<el-button @click="clearMessage">清空</el-button>
</div>
</template>
<script>
export default {
data() {
return {
messageCount: 0
}
},
methods: {
addMessage() {
this.messageCount++;
},
clearMessage() {
this.messageCount = 0;
}
}
}
</script>
说明:动态更新标记的数值。
3.10 组合使用
<template>
<div>
<!-- 小圆点 + 危险类型 -->
<el-badge is-dot type="danger">
<el-button>紧急消息</el-button>
</el-badge>
<!-- 最大值 + 成功类型 -->
<el-badge :value="150" :max="99" type="success">
<el-button>已完成</el-button>
</el-badge>
<!-- 自定义文本 + 警告类型 -->
<el-badge value="NEW" type="warning">
<el-button>新品</el-button>
</el-badge>
</div>
</template>
说明:组合使用多个属性。
四、核心知识点总结
4.1 Vue 组件开发
-
插槽(Slot):
- 默认插槽的使用
- 灵活的内容分发
$slots.default检测插槽内容
-
Props 定义:
- 类型检查:
[String, Number] - 默认值:
default: 200 - 自定义验证器:
validator - 布尔值简写:
isDot: Boolean
- 类型检查:
-
计算属性(Computed):
- 封装复杂逻辑
- 自动缓存
- 响应式更新
-
条件渲染:
v-show:切换显示/隐藏- 复杂条件表达式
- 注意 falsy 值的处理
-
动态类名:
- 数组语法
- 对象语法
- 条件类名
4.2 过渡动画
-
Transition 组件:
- 内置过渡组件
- 自动添加/移除 CSS 类
- 配合 CSS 实现动画效果
-
动画类型:
el-zoom-in-center:缩放淡入el-fade-in:淡入淡出
4.3 样式设计
-
定位方式:
is-fixed:绝对定位- 相对于父元素定位
- 右上角固定位置
-
颜色系统:
- 语义化颜色
- primary、success、warning、info、danger
- 统一的设计语言
-
响应式设计:
- 适配不同屏幕尺寸
- 保持视觉一致性
4.4 用户体验
-
视觉反馈:
- 动画过渡
- 平滑显示/隐藏
- 吸引用户注意
-
信息层次:
- 数字标记:显示具体数量
- 小圆点:简洁的状态指示
- 最大值限制:避免信息过载
-
灵活配置:
- 多种显示模式
- 可自定义颜色
- 可控制显示/隐藏
4.5 最佳实践
-
属性验证:
- 使用
validator验证属性值 - 提供友好的错误提示
- 确保组件的健壮性
- 使用
-
性能优化:
- 使用计算属性缓存结果
- 避免不必要的计算
- 使用
v-show而非v-if(频繁切换时)
-
代码可读性:
- 清晰的命名
- 合理的注释
- 逻辑分层
五、常见问题
5.1 为什么 value 为 0 时不显示?
原因:
- 0 在 JavaScript 中是 falsy 值
- 如果条件是
v-show="content",0 会被隐藏
解决方法:
v-show="!hidden && (content || content === 0 || isDot)"
- 明确判断
content === 0 - 确保 0 也能显示
5.2 如何自定义标记的位置?
方法:通过 CSS 覆盖默认样式。
<template>
<el-badge :value="5" class="custom-badge">
<el-button>消息</el-button>
</el-badge>
</template>
<style>
.custom-badge .el-badge__content {
top: -10px;
right: -10px;
}
</style>
5.3 如何自定义标记的颜色?
方法 1:使用 type 属性
<el-badge :value="5" type="danger"></el-badge>
方法 2:通过 CSS 覆盖
<template>
<el-badge :value="5" class="custom-color">
<el-button>消息</el-button>
</el-badge>
</template>
<style>
.custom-color .el-badge__content {
background-color: #ff6b6b;
}
</style>
5.4 为什么 max 不生效?
原因:
value不是数字类型max不是数字类型- 两者必须都是数字类型
解决方法:
<!-- 正确:都是数字 -->
<el-badge :value="120" :max="99"></el-badge>
<!-- 错误:value 是字符串 -->
<el-badge value="120" :max="99"></el-badge>
<!-- 错误:max 是字符串 -->
<el-badge :value="120" max="99"></el-badge>
5.5 如何实现动态更新标记?
方法:使用响应式数据。
<template>
<el-badge :value="count">
<el-button>消息</el-button>
</el-badge>
</template>
<script>
export default {
data() {
return {
count: 0
}
},
mounted() {
// 模拟接收新消息
setInterval(() => {
this.count++;
}, 5000);
}
}
</script>
5.6 如何在多个元素上使用标记?
方法:为每个元素单独包裹 el-badge。
<template>
<div>
<el-badge :value="5">
<el-button>消息</el-button>
</el-badge>
<el-badge :value="3">
<el-button>评论</el-button>
</el-badge>
<el-badge :value="1">
<el-button>回复</el-button>
</el-badge>
</div>
</template>
六、扩展建议
6.1 功能扩展
- 自定义动画:添加
animation属性 - 点击事件:添加
@click事件 - 自定义位置:添加
position属性(top-right、top-left、bottom-right、bottom-left) - 自定义大小:添加
size属性(small、medium、large) - 自定义图标:在小圆点中显示图标
6.2 样式扩展
- 渐变背景:支持渐变色
- 边框样式:添加边框选项
- 阴影效果:添加阴影样式
- 自定义形状:方形、圆形、胶囊形
- 自定义字体:字体大小、字体粗细
6.3 交互扩展
- 悬停提示:添加 Tooltip
- 点击跳转:点击标记跳转到指定页面
- 长按操作:长按显示详细信息
- 拖拽功能:拖拽标记到其他位置
- 动画效果:更多动画选项
七、与其他组件的配合
7.1 配合 Button 组件
<el-badge :value="12">
<el-button type="primary">消息</el-button>
</el-badge>
7.2 配合 Icon 组件
<el-badge :value="5" is-dot>
<el-icon :size="24">
<bell />
</el-icon>
</el-badge>
7.3 配合 Avatar 组件
<el-badge :value="2" is-dot>
<el-avatar :size="40" src="user.jpg"></el-avatar>
</el-badge>
7.4 配合 Card 组件
<el-badge :value="5" type="danger">
<el-card>
卡片内容
</el-card>
</el-badge>
7.5 配合 Menu 组件
<el-menu>
<el-menu-item>
<el-badge :value="12">
<span>消息</span>
</el-badge>
</el-menu-item>
</el-menu>
八、总结
ElBadge 是一个简单但功能强大的标记组件。通过学习这个组件,我们掌握了:
- Vue 组件基础:Props、插槽、计算属性、条件渲染
- 动态类名:灵活的样式绑定方式
- 过渡动画:使用 Transition 组件实现动画效果
- 属性验证:使用 validator 确保属性值的正确性
- 用户体验设计:信息层次、视觉反馈、灵活配置
这个组件虽然代码量不大,但包含了 Vue 组件开发的许多核心概念,是学习组件开发的优秀示例。它的设计思路和实现方式可以应用到其他类似的组件中。