Element Plus Tag 标签组件完整指南:从基础用法到 CheckTag 可选中标签
【免费下载链接】element-plus🎉 A Vue.js 3 UI Library made by Element team项目地址: https://gitcode.com/GitHub_Trending/el/element-plus
导读
本文围绕 Element Plus(Vue 3 UI 组件库)中的 Tag 标签组件展开,系统讲解其类型(type)、尺寸(size)、主题(effect)、可关闭、可编辑、圆角与可选中(CheckTag)等全部能力,并深入源码验证底层实现原理。读完本文,你将掌握 Tag 组件的全部 API 用法,能够结合实际业务构建动态标签输入、分类筛选、状态标记等实战场景。
官方文档位置:docs/en-US/component/tag.md,对应示例位于 docs/examples/tag。
基本用法:用 type 定义标签类型
Tag 组件用于"标记与选择"(Used for marking and selection)。通过type属性可以定义 Tag 的类型,同时color属性可用于直接设置标签的背景色。
五种内置类型分别对应不同的语义色:primary(主色)、success(成功)、info(信息)、warning(警告)、danger(危险),默认值为primary。
示例代码(完整代码见 docs/examples/tag/basic.vue):
<template> <div class="flex gap-2"> <el-tag type="primary">Tag 1</el-tag> <el-tag type="success">Tag 2</el-tag> <el-tag type="info">Tag 3</el-tag> <el-tag type="warning">Tag 4</el-tag> <el-tag type="danger">Tag 5</el-tag> </div> </template>自定义背景色:color属性接收任意合法 CSS 颜色字符串(如#409EFF),会被直接内联到标签根元素的background-color样式上。从源码 packages/components/tag/src/tag.vue 可以看到,渲染时通过:style="{ backgroundColor: color }"动态应用,因此color的优先级高于type对应的主题色,适合品牌色定制场景。
可移除标签(Removable Tag)
设置closable属性(接受Boolean)即可让标签显示关闭按钮,点击后触发close事件并移除标签。
默认情况下,标签移除时带有淡出(fading)动画——该动画由源码中的transition包裹实现,使用el-zoom-in-center过渡效果(见 packages/components/tag/src/tag.vue)。如果不需要动画,可以设置disable-transitions属性为true,此时将直接渲染为普通<span>而不再套用transition。
示例代码(完整代码见 docs/examples/tag/removable.vue):
<template> <div class="flex gap-2"> <el-tag v-for="tag in tags" :key="tag.name" closable :type="tag.type"> {{ tag.name }} </el-tag> </div> </template> <script lang="ts" setup> import { ref } from 'vue' import type { TagProps } from 'element-plus' interface TagsItem { name: string type: TagProps['type'] } const tags = ref<TagsItem[]>([ { name: 'Tag 1', type: 'primary' }, { name: 'Tag 2', type: 'success' }, { name: 'Tag 3', type: 'info' }, { name: 'Tag 4', type: 'warning' }, { name: 'Tag 5', type: 'danger' }, ]) </script>从源码实现看,关闭按钮是一个真实的<button type="button">元素,带aria-label无障碍标签(内容来自国际化文案el.tag.close),内部渲染Close图标,并通过@click.stop阻止事件冒泡后再触发close事件(见 packages/components/tag/src/tag.vue)。这意味着点击关闭按钮不会同时触发标签的click事件。
动态编辑标签(Edit Dynamically)
借助close事件,可以轻松实现"新增/删除标签"的完整交互闭环:点击标签的关闭按钮移除标签;点击"New Tag"按钮显示输入框,输入内容后按回车或失焦确认并追加新标签。
示例代码(完整代码见 docs/examples/tag/editable.vue):
<template> <div class="flex gap-2"> <el-tag v-for="tag in dynamicTags" :key="tag" closable :disable-transitions="false" @close="handleClose(tag)" > {{ tag }} </el-tag> <el-input v-if="inputVisible" ref="InputRef" v-model="inputValue" class="w-20" size="small" @keyup.enter="handleInputConfirm" @blur="handleInputConfirm" /> <el-button v-else class="button-new-tag" size="small" @click="showInput"> + New Tag </el-button> </div> </template> <script lang="ts" setup> import { nextTick, ref } from 'vue' import type { InputInstance } from 'element-plus' const inputValue = ref('') const dynamicTags = ref(['Tag 1', 'Tag 2', 'Tag 3']) const inputVisible = ref(false) const InputRef = ref<InputInstance>() const handleClose = (tag: string) => { dynamicTags.value.splice(dynamicTags.value.indexOf(tag), 1) } const showInput = () => { inputVisible.value = true nextTick(() => { InputRef.value!.input!.focus() }) } const handleInputConfirm = () => { if (inputValue.value) { dynamicTags.value.push(inputValue.value) } inputVisible.value = false inputValue.value = '' } </script>实现要点:
handleClose通过splice从数组中删除对应标签;showInput切换输入框可见状态,并借助nextTick在 DOM 更新后自动聚焦输入框;handleInputConfirm同时绑定keyup.enter与blur,两个操作路径都能完成"确认新增",其中@click.stop(源码内部)与stop语义保持一致,避免交互冲突;- 标签的
@close会收到原生MouseEvent事件对象,示例中直接用标签文本作为标识进行删除。
这是典型的"标签输入器"(类似邮件收件人输入)场景的基础范式,可在此基础上扩展防重复校验、最大数量限制等业务逻辑。
尺寸(Sizes)
除默认尺寸外,Tag 组件还提供了三种可选尺寸:large、default、small,通过size属性设置。当不传size时,标签会继承外层el-form/el-form-item的size配置——源码中使用useFormSize()获取表单上下文尺寸(见 packages/components/tag/src/tag.vue),这与 Button、Input 等组件的尺寸联动行为保持一致。
示例代码(完整代码见 docs/examples/tag/sizes.vue):
<template> <div class="flex gap-2"> <el-tag size="large">Large</el-tag> <el-tag>Default</el-tag> <el-tag size="small">Small</el-tag> </div> </template>size的合法取值定义在常量componentSizes中,即'large' | 'default' | 'small'(见 packages/components/tag/src/tag.ts)。
主题(Theme)
Tag 提供三种主题:dark、light、plain,通过effect属性切换,默认值为light。
dark:实心深色背景 + 白色文字,对比最强;light:浅色背景 + 深色文字,柔和醒目,是默认主题;plain:白色/极浅背景 + 描边 + 主题色文字,视觉最轻。
示例代码(完整代码见 docs/examples/tag/theme.vue):
<template> <div class="flex gap-2"> <span>Dark</span> <el-tag v-for="item in items" :key="item.label" :type="item.type" effect="dark" > {{ item.label }} </el-tag> </div> <div class="flex gap-2 mt-4"> <span>Light</span> <el-tag v-for="item in items" :key="item.label" :type="item.type" effect="light" > {{ item.label }} </el-tag> </div> <div class="flex gap-2 mt-4"> <span>Plain</span> <el-tag v-for="item in items" :key="item.label" :type="item.type" effect="plain" > {{ item.label }} </el-tag> </div> </template> <script lang="ts" setup> import { ref } from 'vue' import type { TagProps } from 'element-plus' type Item = { type: TagProps['type']; label: string } const items = ref<Array<Item>>([ { type: 'primary', label: 'Tag 1' }, { type: 'success', label: 'Tag 2' }, { type: 'info', label: 'Tag 3' }, { type: 'warning', label: 'Tag 4' }, { type: 'danger', label: 'Tag 5' }, ]) </script>三种主题 × 五种类型可以自由组合,覆盖绝大多数状态标记场景,例如danger+dark用于强提示、success+plain用于弱化展示。
圆角标签(Rounded)
与 Button 类似,Tag 也可以设置为圆角样式,只需添加round属性即可。圆角后的标签在胶囊形筛选条、趋势词云等场景中更常见。
示例代码(完整代码见 docs/examples/tag/rounded.vue):
<template> <div class="flex gap-2"> <el-tag v-for="item in items" :key="item.label" :type="item.type" effect="dark" round > {{ item.label }} </el-tag> </div> <div class="flex gap-2 mt-4"> <el-tag v-for="item in items" :key="item.label" :type="item.type" effect="light" round > {{ item.label }} </el-tag> </div> <div class="flex gap-2 mt-4"> <el-tag v-for="item in items" :key="item.label" :type="item.type" effect="plain" round > {{ item.label }} </el-tag> </div> </template>从源码看,round与type、hit、effect、closable、size一起参与containerKls的类名计算(见 packages/components/tag/src/tag.vue),样式由is-round修饰类驱动,主题样式定义在 theme-chalk 的 tag.scss 中。
可选中标签(CheckTag)
有些业务需要"复选框式"的标签:选中 / 未选中二态切换,但 Button 形态的 checkbox 又无法满足需求,此时应使用check-tag(即el-check-tag组件)。它的 API 非常简单:
checked / v-model:checked:是否选中(Boolean,默认false);disabled:是否禁用(Boolean,默认false,自 ^(2.8.2) 起支持);type:CheckTag 的类型(自 ^(2.5.4) 起支持,取值'primary' | 'success' | 'info' | 'warning' | 'danger',默认primary);change事件:点击时触发,回调参数为切换后的布尔值(value: boolean) => void。
示例代码(完整代码见 docs/examples/tag/checkable.vue):
<template> <div class="flex gap-2"> <el-check-tag checked>Checked</el-check-tag> <el-check-tag :checked="checked" @change="onChange">Toggle me</el-check-tag> <el-check-tag disabled>Disabled</el-check-tag> </div> <div class="flex gap-2 mt-4"> <el-check-tag :checked="checked1" type="primary" @change="onChange1"> Tag 1 </el-check-tag> <el-check-tag :checked="checked2" type="success" @change="onChange2"> Tag 2 </el-check-tag> <el-check-tag :checked="checked3" type="info" @change="onChange3"> Tag 3 </el-check-tag> <el-check-tag :checked="checked4" type="warning" @change="onChange4"> Tag 4 </el-check-tag> <el-check-tag :checked="checked5" type="danger" @change="onChange5"> Tag 5 </el-check-tag> <el-check-tag :checked="checked6" disabled type="success" @change="onChange6" > Tag 6 </el-check-tag> </div> </template> <script lang="ts" setup> import { ref } from 'vue' const checked = ref(false) const checked1 = ref(true) const checked2 = ref(true) const checked3 = ref(true) const checked4 = ref(true) const checked5 = ref(true) const checked6 = ref(true) const onChange = (status: boolean) => { checked.value = status } // onChange1 ~ onChange6 同理,将 status 写入对应 ref </script>从源码 packages/components/check-tag/src/check-tag.vue 可以看到其实现逻辑:
- 点击根元素触发
handleChange; - 若
disabled为true则直接return,不产生任何事件; - 否则取反得到
checked = !props.checked,同时派发change事件与update:checked事件,因此既支持@change监听,也天然支持v-model:checked双向绑定; - 类名计算中通过
is-checked、is-disabled以及m(type)三个修饰类控制选中态、禁用态与类型配色。
组件是一个"受控 + 半受控"结合的轻量实现:即使不写v-model,点击也会通过change事件把新状态交还给你手动维护。
Tag API 完整参考
以下内容与官方文档 docs/en-US/component/tag.md 保持一致,并结合源码 packages/components/tag/src/tag.ts 补充取值与默认值说明。
Tag Attributes
| 名称 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| type | Tag 类型 | ^[enum]'primary' \| 'success' \| 'info' \| 'warning' \| 'danger' | primary |
| closable | 是否可移除 | ^[boolean] | false |
| disable-transitions | 是否禁用动画 | ^[boolean] | false |
| hit | 是否有高亮边框 | ^[boolean] | false |
| color | Tag 背景色 | ^[string] | — |
| size | Tag 尺寸 | ^[enum]'large' \| 'default' \| 'small' | — |
| effect | Tag 主题 | ^[enum]'dark' \| 'light' \| 'plain' | light |
| round | 是否为圆角 | ^[boolean] | false |
补充说明:
type的默认值primary与effect的默认值light在源码withDefaults与buildProps中均有双重定义(见 packages/components/tag/src/tag.vue);size未设置时继承表单上下文尺寸(useFormSize),因此放在el-form中的 Tag 会自动跟随表单尺寸;hit表示"命中高亮":用于搜索结果等场景下标记命中的标签,会呈现高亮描边效果;disable-transitions为true时源码直接渲染纯<span>分支(无transition包裹),同时保留el-zoom-in-center过渡的引入,仅作为关闭动画的手段。
Tag Events
| 名称 | 说明 | 类型 |
|---|---|---|
| click | 点击 Tag 时触发 | ^[Function](evt: MouseEvent) => void |
| close | 移除 Tag 时触发 | ^[Function](evt: MouseEvent) => void |
源码中tagEmits对两个事件均做了evt instanceof MouseEvent的类型守卫校验(见 packages/components/tag/src/tag.ts),不符合预期的调用会在开发期收到类型告警。
Tag Slots
| 名称 | 说明 |
|---|---|
| default | 自定义默认内容 |
CheckTag API 完整参考
CheckTag Attributes
| 名称 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| checked / v-model:checked | 是否选中 | ^[boolean] | false |
| disabled ^(2.8.2) | 是否禁用 | ^[boolean] | false |
| type ^(2.5.4) | CheckTag 类型 | ^[enum]'primary' \| 'success' \| 'info' \| 'warning' \| 'danger' | primary |
CheckTag Events
| 名称 | 说明 | 类型 |
|---|---|---|
| change | 点击 Check Tag 时触发 | ^[Function](value: boolean) => void |
CheckTag Slots
| 名称 | 说明 |
|---|---|
| default | 自定义默认内容 |
源码层面的实现细节
1. 关闭按钮的可用性与事件隔离
关闭按钮使用原生<button type="button">并携带aria-label(文案来自useLocale国际化表el.tag.close),保证键盘可聚焦、屏幕阅读器可读。@click.stop确保点击关闭按钮只触发close而不会连带触发click。
2. 过渡动画的取舍
disable-transitions直接决定渲染分支:false(默认)时外层包一层<transition name="el-zoom-in-center" appear>,标签挂载与移除均有缩放 + 淡出动效;true时退化为普通元素,适合高频增删、追求极简交互的场景。
3. 类型体系与扩展约定
TagProps接口与tagProps运行时 props 同时存在,其中tagProps与TagPropsPublic均被标记为@deprecated("Removed after 3.0.0, UseTagPropsinstead",见 packages/components/tag/src/tag.ts),即推荐直接使用类型层面的TagProps进行 TS 推导(如示例中的TagProps['type']),运行时 props 结构保持兼容。组件测试见 packages/components/tag/tests/tag.test.tsx。
4. 与表单体系的联动
useFormSize()让 Tag 无需显式传size也能与el-form/el-form-item的尺寸配置保持一致,这在批量渲染标签的场景(如表格操作列、筛选器)中非常实用,避免逐个设置尺寸。
总结:按场景选型
| 业务场景 | 推荐方案 |
|---|---|
| 静态状态展示 | <el-tag>+type+effect |
| 搜索结果命中高亮 | <el-tag hit> |
| 可删除的筛选条件 | <el-tag closable @close="..."> |
| 动态新增/删除标签 | 复用editable示例中的 输入框 + 按钮 闭环 |
| 需要切换选中态的标签 | <el-check-tag v-model:checked> |
| 禁用状态的可选标签 | <el-check-tag disabled>(自 2.8.2 起) |
| 自定义品牌背景色 | <el-tag color="#xxx"> |
从基础的类型与主题,到可关闭、动态编辑,再到 CheckTag 的可选中交互,Tag 家族覆盖了"标记与选择"的绝大多数使用场景。结合源码阅读,可以看到其在事件隔离、无障碍(aria-label)、表单尺寸联动与受控状态管理上的细致设计,值得在实现自定义标签类组件时参考。
【免费下载链接】element-plus🎉 A Vue.js 3 UI Library made by Element team项目地址: https://gitcode.com/GitHub_Trending/el/element-plus
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考