前言

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net

OpenHarmony 跨平台开发中,标签组件是一个非常常见的 UI 元素。无论是文章分类、用户画像、产品筛选还是技能展示,标签都能提供简洁直观的信息标记方式。本文将详细介绍 VCordova v1.6.0 中标签组件的适配过程,涵盖多种标签类型标签大小可关闭标签标签输入框等核心功能。

在前面的版本中,我们已经完成了数据展示、图表、弹窗、日期选择、下拉菜单和文件上传等组件的适配。本次 v1.6.0 版本重点聚焦于标签组件,为开发者提供一套完整的标签展示与管理方案。

本文基于 VCordova 三方库适配 OpenHarmony 的实践经验撰写,适合有一定前端基础的开发者阅读。


一、UI 展示效果

1.1 标签展示

在这里插入图片描述

上图展示了标签组件在 OpenHarmony 设备上的实际运行效果,包括不同类型、不同大小的标签以及标签输入框。

1.2 组件功能概览

VCordova v1.6.0 标签组件提供了以下核心功能:

  1. 六种标签类型(default/primary/success/warning/error/info)
  2. 三种标签大小(small/medium/large)
  3. 可关闭标签
  4. 带图标标签
  5. 标签点击事件
  6. 动态标签管理(增删改查)
  7. 标签输入框组件

1.3 组件特性一览

特性 支持情况 说明
多种类型 ✅ 支持 default/primary/success/warning/error/info
多种大小 ✅ 支持 small/medium/large 三种尺寸
可关闭 ✅ 支持 点击 × 按钮关闭标签
带图标 ✅ 支持 标签文字左侧显示图标
点击事件 ✅ 支持 点击标签触发回调
动态管理 ✅ 支持 增删改查标签列表
标签输入框 ✅ 支持 输入框动态添加标签

提示:标签组件同时提供了静态展示和动态管理两种使用方式,开发者可以根据业务需求灵活选择。


二、快速上手

2.1 引入文件

使用标签组件前,需要先引入对应的 CSS 和 JS 文件:

<link rel="stylesheet" href="components/tag/tag.css">
<script src="components/tag/tag.js"></script>

CSS 文件包含标签组件的所有样式定义,包括不同类型、大小的样式。JS 文件包含 Tag 类和 TagInput 类的完整实现。

2.2 创建容器

标签组件需要一个 HTML 容器元素来挂载:

<div id="tagContainer"></div>

容器可以是任何 HTML 元素,只需要设置一个唯一的 id 属性即可。组件会自动在容器内渲染标签列表。

2.3 初始化标签组件

通过创建 Tag 实例来初始化标签组件:

const tag = new Tag({
    container: '#tagContainer',
    tags: ['标签1', '标签2', '标签3'],
    type: 'primary',
    closable: true
});

初始化配置参数说明:

参数 类型 默认值 说明
container String 必填 容器选择器,支持 CSS 选择器语法
tags Array [] 标签列表,支持字符串数组或对象数组
type String ‘default’ 标签类型
size String ‘medium’ 标签大小:small/medium/large
closable Boolean false 是否显示关闭按钮
onClick Function null 标签点击回调
onClose Function null 标签关闭回调

2.4 快速上手完整示例

下面是一个完整的快速上手示例,展示如何在页面中创建标签组件:

<!DOCTYPE html>
<html>
<head>
    <link rel="stylesheet" href="components/tag/tag.css">
</head>
<body>
    <h2>标签组件示例</h2>
    <div id="myTags"></div>
    <div id="result"></div>

    <script src="components/tag/tag.js"></script>
    <script>
        const tag = new Tag({
            container: '#myTags',
            tags: [
                { label: 'JavaScript', type: 'primary' },
                { label: 'Python', type: 'success' },
                { label: 'Java', type: 'warning' }
            ],
            closable: true,
            onClick: (result) => {
                document.getElementById('result').innerHTML =
                    '点击了:' + result.tag;
            },
            onClose: (result) => {
                document.getElementById('result').innerHTML =
                    '关闭了:' + result.tag;
            }
        });
    </script>
</body>
</html>

上述代码创建了三个不同类型的可关闭标签,点击或关闭标签时会在页面上显示操作结果。


三、标签类型详解

标签组件支持六种类型,每种类型对应不同的颜色和语义。

3.1 六种标签类型

const tag = new Tag({
    container: '#tagContainer',
    tags: [
        { label: '默认', type: 'default' },
        { label: '主色', type: 'primary' },
        { label: '成功', type: 'success' },
        { label: '警告', type: 'warning' },
        { label: '错误', type: 'error' },
        { label: '信息', type: 'info' }
    ]
});

每种类型都有明确的语义和视觉表现。

3.2 类型详细说明

  • default — 默认类型,灰色背景,用于普通标签和通用分类
  • primary — 主色类型,蓝色背景,用于重要标签和主要分类
  • success — 成功类型,绿色背景,用于成功状态和正向标记
  • warning — 警告类型,橙色背景,用于警告信息和需注意项
  • error — 错误类型,红色背景,用于错误信息和负向标记
  • info — 信息类型,浅蓝背景,用于信息提示和辅助说明

3.3 类型颜色对照表

类型 背景色 文字色 边框色 适用场景
default #f0f0f0 #666666 #d9d9d9 通用标签
primary #409EFF #ffffff #409EFF 重要标签
success #67C23A #ffffff #67C23A 成功状态
warning #E6A23C #ffffff #E6A23C 警告提示
error #F56C6C #ffffff #F56C6C 错误标记
info #909399 #ffffff #909399 信息提示

3.4 类型样式的 CSS 实现

标签类型的样式通过 CSS 类名实现:

/* 默认标签 */
.tag {
    display: inline-flex;
    align-items: center;
    padding: 4px 10px;
    border-radius: 4px;
    font-size: 12px;
    line-height: 1;
    border: 1px solid #d9d9d9;
    background-color: #f0f0f0;
    color: #666666;
    cursor: default;
    margin: 2px 4px;
}

/* 主色标签 */
.tag--primary {
    background-color: #409EFF;
    border-color: #409EFF;
    color: #ffffff;
}

/* 成功标签 */
.tag--success {
    background-color: #67C23A;
    border-color: #67C23A;
    color: #ffffff;
}

/* 警告标签 */
.tag--warning {
    background-color: #E6A23C;
    border-color: #E6A23C;
    color: #ffffff;
}

/* 错误标签 */
.tag--error {
    background-color: #F56C6C;
    border-color: #F56C6C;
    color: #ffffff;
}

/* 信息标签 */
.tag--info {
    background-color: #909399;
    border-color: #909399;
    color: #ffffff;
}

提示:标签类型的颜色方案与 VCordova 组件库的整体设计规范保持一致,确保视觉统一。


四、标签大小

标签组件支持三种大小,适应不同的布局需求。

4.1 三种大小示例

const tag = new Tag({
    container: '#tagContainer',
    tags: [
        { label: '小标签', size: 'small' },
        { label: '中标签', size: 'medium' },
        { label: '大标签', size: 'large' }
    ]
});

4.2 大小详细说明

每种大小有不同的内边距和字号:

  • small — 小标签,padding: 2px 6pxfont-size: 10px,适合紧凑布局
  • medium — 中标签,padding: 4px 10pxfont-size: 12px,默认大小
  • large — 大标签,padding: 6px 14pxfont-size: 14px,适合突出显示

4.3 大小尺寸对照

大小 内边距 字号 行高 适用场景
small 2px 6px 10px 1 表格内、紧凑列表
medium 4px 10px 12px 1 通用场景、默认选择
large 6px 14px 14px 1.2 标题区域、突出展示

4.4 大小样式的 CSS 实现

/* 小标签 */
.tag--small {
    padding: 2px 6px;
    font-size: 10px;
}

/* 中标签(默认) */
.tag--medium {
    padding: 4px 10px;
    font-size: 12px;
}

/* 大标签 */
.tag--large {
    padding: 6px 14px;
    font-size: 14px;
    line-height: 1.2;
}

五、可关闭标签

标签可以设置为可关闭,用户点击关闭按钮即可移除标签。

5.1 启用关闭功能

const tag = new Tag({
    container: '#tagContainer',
    tags: ['JavaScript', 'Python', 'Java', 'Go'],
    closable: true,
    onClose: (result) => {
        console.log('关闭标签:', result.tag);
        console.log('标签索引:', result.index);
    }
});

设置 closable: true 即可在每个标签右侧显示 × 关闭按钮。

5.2 关闭回调参数

onClose 回调函数接收一个结果对象:

onClose: (result) => {
    // result.tag   - 被关闭的标签文本
    // result.index - 被关闭标签的索引位置
    // result.tags  - 关闭后剩余的标签列表
    console.log('关闭了:', result.tag);
    console.log('剩余标签:', result.tags);
}

5.3 关闭按钮样式

关闭按钮的 CSS 样式:

/* 关闭按钮 */
.tag-close {
    margin-left: 4px;
    font-size: 12px;
    cursor: pointer;
    opacity: 0.6;
    transition: opacity 0.2s ease;
}

.tag-close:hover {
    opacity: 1;
}

关闭按钮默认半透明,鼠标悬停时变为完全不透明,提供清晰的交互反馈。

注意:关闭标签后,组件会自动更新内部标签列表,无需手动调用删除方法。


六、带图标标签

标签可以在文字左侧显示图标,增强视觉辨识度。

6.1 添加图标

const tag = new Tag({
    container: '#tagContainer',
    tags: [
        { label: 'JavaScript', icon: '📜', type: 'primary' },
        { label: 'Python', icon: '🐍', type: 'success' },
        { label: 'Java', icon: '☕', type: 'warning' },
        { label: 'Go', icon: '🔵', type: 'info' },
        { label: 'Rust', icon: '⚙️', type: 'error' }
    ]
});

在标签对象中添加 icon 属性即可显示图标。图标显示在标签文字的左侧,与文字之间有适当间距。

6.2 图标样式

/* 标签图标 */
.tag-icon {
    margin-right: 4px;
    font-size: inherit;
    line-height: 1;
}

6.3 图标使用建议

图标的选择建议:

  • 使用 Emoji 图标,兼容性好,无需额外引入图标库
  • 使用 SVG 图标,可自定义颜色和大小
  • 使用 图标字体(如 iconfont),适合统一的图标风格

七、标签点击事件

标签可以响应点击事件,实现标签筛选、标签选中等交互。

7.1 点击回调

const tag = new Tag({
    container: '#tagContainer',
    tags: ['前端', '后端', '移动端', '运维'],
    onClick: (result) => {
        console.log('点击标签:', result.tag);
        console.log('标签索引:', result.index);
    }
});

onClick 回调在用户点击标签时触发,接收标签信息作为参数。

7.2 标签选中效果

结合点击事件可以实现标签选中效果:

const tag = new Tag({
    container: '#tagContainer',
    tags: ['全部', '技术', '生活', '随笔'],
    onClick: (result) => {
        // 高亮选中的标签
        tag.setActiveTag(result.index);
        // 根据标签筛选内容
        filterContent(result.tag);
    }
});

function filterContent(category) {
    console.log('筛选分类:', category);
    // 执行筛选逻辑
}

7.3 选中状态样式

/* 标签选中状态 */
.tag--active {
    box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.3);
    transform: scale(1.05);
    transition: all 0.2s ease;
}

选中的标签会有外发光效果和轻微放大,提供清晰的视觉反馈。


八、动态标签管理

组件提供了完善的标签管理 API,支持动态增删改查。

8.1 添加标签

// 添加单个标签
tag.addTag('新标签');

// 添加带配置的标签
tag.addTag({ label: 'TypeScript', type: 'primary', icon: '📘' });

// 批量添加标签
tag.addTags(['标签A', '标签B', '标签C']);

addTag() 方法支持字符串和对象两种参数格式。addTags() 方法支持批量添加。

8.2 删除标签

// 按索引删除
tag.removeTag(0);

// 按标签值删除
tag.removeTagByValue('标签1');

removeTag() 按索引删除,removeTagByValue() 按标签文本删除。

8.3 获取与设置标签

// 获取所有标签
const allTags = tag.getTags();
console.log('当前标签:', allTags);

// 替换所有标签
tag.setTags(['新标签1', '新标签2', '新标签3']);

// 清空所有标签
tag.clearTags();

8.4 标签管理 API 汇总

方法 参数 返回值 说明
addTag(tag) String/Object void 添加单个标签
addTags(tags) Array void 批量添加标签
removeTag(index) Number void 按索引删除标签
removeTagByValue(value) String void 按值删除标签
getTags() Array 获取所有标签
setTags(tags) Array void 替换所有标签
clearTags() void 清空所有标签
destroy() void 销毁组件实例

九、标签输入框组件

标签输入框是标签组件的重要补充,允许用户通过输入框动态添加和管理标签。

9.1 初始化标签输入框

const tagInput = new TagInput({
    container: '#tagInputContainer',
    placeholder: '输入标签后按 Enter',
    maxTags: 10,
    onTagAdd: (result) => {
        console.log('添加标签:', result.tag);
    },
    onTagRemove: (result) => {
        console.log('删除标签:', result.tag);
    }
});

9.2 标签输入框配置参数

参数 类型 默认值 说明
container String 必填 容器选择器
placeholder String ‘输入标签’ 输入框占位文本
maxTags Number 10 最大标签数量
separator String ‘,’ 标签分隔符
allowDuplicate Boolean false 是否允许重复标签
onTagAdd Function null 添加标签回调
onTagRemove Function null 删除标签回调
onChange Function null 标签变化回调

9.3 标签输入交互方式

标签输入框支持多种交互方式:

  1. 输入文字后按 Enter 键添加标签
  2. 输入文字后按分隔符(默认逗号)添加标签
  3. 点击标签上的 × 按钮删除标签
  4. 输入框为空时按 Backspace 键删除最后一个标签

9.4 标签输入框完整示例

<div id="tagInputDemo"></div>
<button onclick="getInputTags()">获取标签</button>
<div id="tagResult"></div>

<script>
    const tagInput = new TagInput({
        container: '#tagInputDemo',
        placeholder: '输入技能标签,按 Enter 添加',
        maxTags: 8,
        allowDuplicate: false,
        onTagAdd: (result) => {
            console.log('添加了:', result.tag);
        },
        onTagRemove: (result) => {
            console.log('删除了:', result.tag);
        },
        onChange: (tags) => {
            console.log('当前标签:', tags);
        }
    });

    function getInputTags() {
        const tags = tagInput.getTags();
        document.getElementById('tagResult').innerHTML =
            '当前标签:' + tags.join(', ');
    }
</script>

9.5 标签输入框 API

// 添加标签
tagInput.addTag('新标签');

// 删除标签(按索引)
tagInput.removeTag(0);

// 获取所有标签
const tags = tagInput.getTags();

// 替换所有标签
tagInput.setTags(['标签1', '标签2']);

// 清空所有标签
tagInput.clearTags();

提示:标签输入框会自动去除输入内容的首尾空格,并在 allowDuplicate: false 时自动过滤重复标签。


十、标签输入框样式定制

标签输入框的样式可以通过 CSS 进行定制。

10.1 默认样式

/* 标签输入框容器 */
.tag-input-wrapper {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    padding: 4px 8px;
    border: 1px solid #d9d9d9;
    border-radius: 4px;
    min-height: 36px;
    cursor: text;
    transition: border-color 0.3s ease;
}

/* 聚焦状态 */
.tag-input-wrapper:focus-within {
    border-color: #409EFF;
    box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.2);
}

/* 输入框 */
.tag-input-wrapper input {
    border: none;
    outline: none;
    flex: 1;
    min-width: 80px;
    font-size: 14px;
    padding: 4px 0;
}

/* 输入框内的标签 */
.tag-input-wrapper .tag {
    margin: 2px 4px 2px 0;
}

10.2 自定义主题色

/* 自定义主题色 */
.tag-input-wrapper:focus-within {
    border-color: #722ED1;
    box-shadow: 0 0 0 2px rgba(114, 46, 209, 0.2);
}

.tag-input-wrapper .tag--primary {
    background-color: #722ED1;
    border-color: #722ED1;
}

通过覆盖 CSS 变量或类名,可以轻松实现自定义主题色。


十一、OpenHarmony 适配要点

在将标签组件适配到 OpenHarmony 平台时,需要注意以下关键点。

11.1 适配注意事项

在 OpenHarmony 环境下使用标签组件,需要关注以下几个方面:

  1. Emoji 图标兼容性:确保 Emoji 在 OpenHarmony WebView 中正常渲染
  2. 触摸事件:标签的点击和关闭交互需要适配触摸事件
  3. 输入法兼容:标签输入框需要处理不同输入法的 Enter 键行为
  4. 字体渲染:不同设备的字体渲染可能导致标签大小差异

11.2 适配代码示例

针对 OpenHarmony 平台的适配代码:

// OpenHarmony 环境检测
function isOpenHarmony() {
    return typeof window !== 'undefined' &&
           navigator.userAgent.indexOf('OpenHarmony') > -1;
}

// 根据平台调整标签配置
function createTag(container, tags) {
    const config = {
        container: container,
        tags: tags,
        closable: true
    };

    // OpenHarmony 设备使用较大的标签尺寸,方便触摸操作
    if (isOpenHarmony()) {
        config.size = 'large';
    }

    return new Tag(config);
}

11.3 已适配组件清单

截至 v1.6.0 版本,VCordova 三方库已适配的组件如下:

版本 组件 状态
v1.0.0 基础数据展示 ✅ 已完成
v1.1.0 图表组件 ✅ 已完成
v1.2.0 弹窗组件 ✅ 已完成
v1.3.0 日期选择器 ✅ 已完成
v1.4.0 下拉菜单 ✅ 已完成
v1.5.0 文件上传 ✅ 已完成
v1.6.0 标签组件 ✅ 已完成
v1.7.0 进度条组件 🔜 开发中
v1.8.0 加载动画 📋 计划中

十二、完整 API 参考

12.1 Tag 类 API

以下是 Tag 类的完整 API 列表:

方法 参数 返回值 说明
addTag(tag) String/Object void 添加单个标签
addTags(tags) Array void 批量添加标签
removeTag(index) Number void 按索引删除标签
removeTagByValue(value) String void 按值删除标签
getTags() Array 获取所有标签
setTags(tags) Array void 替换所有标签
setActiveTag(index) Number void 设置选中标签
clearTags() void 清空所有标签
destroy() void 销毁组件实例

12.2 TagInput 类 API

以下是 TagInput 类的完整 API 列表:

方法 参数 返回值 说明
addTag(tag) String void 添加标签
removeTag(index) Number void 按索引删除标签
getTags() Array 获取所有标签
setTags(tags) Array void 替换所有标签
clearTags() void 清空所有标签
focus() void 聚焦输入框
destroy() void 销毁组件实例

12.3 配置项速查

Tag 组件完整配置项:

const tag = new Tag({
    // 必填项
    container: '#container',     // 容器选择器

    // 可选项
    tags: [],                    // 标签列表
    type: 'default',             // 类型:default/primary/success/warning/error/info
    size: 'medium',              // 大小:small/medium/large
    closable: false,             // 是否可关闭

    // 回调函数
    onClick: null,               // 点击回调
    onClose: null                // 关闭回调
});

TagInput 组件完整配置项:

const tagInput = new TagInput({
    // 必填项
    container: '#container',     // 容器选择器

    // 可选项
    placeholder: '输入标签',      // 占位文本
    maxTags: 10,                 // 最大标签数
    separator: ',',              // 分隔符
    allowDuplicate: false,       // 是否允许重复

    // 回调函数
    onTagAdd: null,              // 添加回调
    onTagRemove: null,           // 删除回调
    onChange: null                // 变化回调
});

十三、常见问题与解决方案

13.1 标签溢出处理

当标签数量过多时,容器可能出现溢出。解决方案:

/* 标签容器自动换行 */
.tag-container {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
}

/* 或者使用滚动 */
.tag-container--scroll {
    display: flex;
    overflow-x: auto;
    white-space: nowrap;
}

两种处理方式:

  • 自动换行 — 适合标签数量不多的场景,所有标签都可见
  • 水平滚动 — 适合标签数量较多的场景,节省垂直空间

13.2 标签输入框回车问题

在某些输入法下,按 Enter 键可能触发输入法确认而非添加标签。解决方案:

inputElement.addEventListener('keydown', (e) => {
    // 使用 keyCode 兼容不同输入法
    if (e.keyCode === 13 && !e.isComposing) {
        e.preventDefault();
        this.addCurrentInput();
    }
});

注意:e.isComposing 属性用于判断当前是否处于输入法组合状态,避免在中文输入过程中误触发添加操作。

13.3 标签重复检测

默认情况下,标签输入框不允许添加重复标签:

addTag(value) {
    const trimmed = value.trim();
    if (!trimmed) return;

    if (!this.allowDuplicate) {
        const exists = this.tags.some(t => t === trimmed);
        if (exists) {
            this.showTip('标签已存在');
            return;
        }
    }

    this.tags.push(trimmed);
    this.render();
}

十四、最佳实践建议

14.1 标签设计建议

在实际项目中使用标签组件时,建议遵循以下设计原则:

  • 标签文字保持简短,建议不超过 8 个字符
  • 同一区域的标签使用统一的类型和大小
  • 可关闭标签适合用于用户自定义标签场景
  • 不可关闭标签适合用于系统预设分类场景

14.2 性能优化建议

  • 避免在同一容器中渲染过多标签(建议不超过 50 个
  • 大量标签场景考虑使用虚拟滚动分页加载
  • 不再使用的组件实例及时调用 destroy() 方法销毁
  • 标签输入框的 onChange 回调中避免执行耗时操作

14.3 无障碍访问

标签组件内置了基本的无障碍支持:

<!-- 标签的无障碍属性 -->
<span class="tag" role="status" aria-label="标签:JavaScript">
    JavaScript
    <button class="tag-close" aria-label="关闭标签 JavaScript">×</button>
</span>

<!-- 标签输入框的无障碍属性 -->
<div class="tag-input-wrapper" role="group" aria-label="标签输入">
    <input type="text" aria-label="输入新标签" placeholder="输入标签后按 Enter">
</div>

组件会自动添加 rolearia-label 属性,确保屏幕阅读器能够正确识别标签内容和交互操作。

14.4 与其他组件配合使用

标签组件可以与 VCordova 的其他组件配合使用:

  • 下拉菜单配合,实现标签筛选功能
  • 弹窗组件配合,在弹窗中编辑标签
  • 文件上传组件配合,为上传文件添加标签分类
  • 图表组件配合,按标签维度展示数据统计

总结

VCordova v1.6.0 标签组件完成了标签展示和管理的全部功能适配。结合前面版本已适配的组件,现在我们拥有了涵盖数据展示、交互、输入、选择、上传和标签的完整解决方案。

标签组件的设计遵循简洁、高效、易用的理念,支持六种类型、三种大小,提供可关闭、带图标、点击事件等丰富功能。同时提供标签输入框组件,满足动态标签管理的需求。

后续版本将继续添加更多组件。下一个版本 v1.7.0 将带来进度条组件,之后还有加载动画、分页等组件。每个组件都将遵循同样的设计理念,为 OpenHarmony 跨平台开发提供开箱即用的 UI 解决方案。

如果这篇文章对你有帮助,欢迎点赞👍、收藏⭐、关注🔔,你的支持是我持续创作的动力!


相关资源:

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐