本文由体验技术团队TinyVue项目组原创。

一、前言

我们非常高兴地宣布,最近,TinyVue发布了 v3.28.0, 这个版本带来了:

  • 选择器组件家族全面重构 - 统一架构,性能提升
  • 主题动画全局配置- 一键定制,随心所欲
  • 65+Bug 及优化修复 - 稳定性大幅提升

详细的 Release Notes 请参考:github.com/opentiny/ti…

本次版本共有 11 位贡献者参与开发,其中 IKEYCY / neostfox 是新朋友,欢迎新朋友的加入,感谢新老朋友们对 TinyVue 的辛苦付出

  • IKEYCY- 新增贡献者
  • neostfox- 新增贡献者
  • shenjunjian
  • kagol
  • zzcr
  • gimmyhehe
  • Davont
  • discreted66
  • wuyiping0628
  • James-9696
  • gausszhou

同时,如果你在使用过程中遇到任何问题,或者有好的建议,欢迎:

  • 提交 Issue
  • 加入讨论
  • 查看文档

二、升级指南

你可以更新 @opentiny/vue@3.28.0 进行体验!

# 安装最新版本

npm install @opentiny/vue@3.28.0

# 或使用 yarn

yarn add @opentiny/vue@3.28.0

如果遇到问题,可以:

查看 Issue - 在 GitHub 上搜索相关问题 提交 Issue - 如果问题未解决,提交新的 Issue

三、特性介绍

下面我们一起来看看都有哪些更新吧!

选择器组件"家族重组"

为什么需要重构?

Select 组件的现状和问题:

  • Select 组件中耦合了 Tree / Grid 两个重型组件,分别对应下拉树和下拉表格两个特性,render-type="tree" | "grid"
  • 下拉树和下拉表格并不是常态,普通的下拉列表才是常态,这就导致了大量只使用Select简单功能的业务包体积也很大,影响业务性能
  • 依赖了 Select 的组件,比如 Area,间接地等于依赖了 Select / Grid / Tree,导致包体积变大
  • 本来应该依赖基于 Select 组件的组件,比如 Pager,由于 Select 耦合了 tree/grid,因此只能自己实现一个 Select,造成重复代码

我们使用 Vite 创建一个空的 Vue 项目,对比下不同情况下构建产物体积情况:

产物体积(css+js, 单位kB)gzip之后的产物体积(单位kB)
不引入TinyVue组件5623
只引入Select组件1777424
只引入Tree组件789190
只引入Grid组件1217302
只引入Button31091
只引入Area组件(依赖Select)1783425

不引入TinyVue组件/只引入Select组件/只引入Tree组件的产物体积对比:

只使用 Area 组件(依赖了Select组件)的产物体积:

可以看到:

  • 只引入 Select 组件,产物里面却同时包含了 tree/grid 两个组件,导致产物体积很大
  • Area 组件本身只是一个很简单的组件,由于引入了 Select,导致产物体积也非常大

重构目标

本次重构主要达成以下目标:

  1. 从 Select 组件中**剥离 Tree / Grid 组件,让业务在单引Select组件时不再包含 tree/grid 两个重型组件
  2. 减少业务单引Select组件(包括TinyVue组件中依赖了Select的组件)时的包体积,优化性能
  3. 重构完不能引起破坏性变更,不能影响现有业务

重构方案

为了达成以上目标,我们设计并实行了以下重构方案:

  1. 开发一个新组件 BaseSelect,这个组件和 Select 组件的api和功能完全一致,只是移除了 tree/grid 相关api和功能
  2. BaseSelect 组件增加panel插槽,并设计好panel与reference的沟通机制,让用户可以在panel插槽放置任意内容,包括tree/grid等组件,从而实现下拉树、下拉表格等功能
  3. 基于 BaseSelect 封装 TreeSelect 组件,实现下拉树组件
  4. 基于 BaseSelect 封装 GridSelect 组件,实现下拉表格组件
  5. 重构 Select,移除原有的 tree/grid 功能,基于 BaseSelect / TreeSeelct / GridSelect 组件进行封装,全新的 Select 组件api和功能与原来的Select组件一模一样,不影响用户使用
  6. 开发全新select-wrapper包装器,包含原本select所有功能用于平替

重构后组件关系如下图:

业务性能优化

使用了 Select 组件的业务,如果想要优化性能,可以:

  • 只需要Select基本功能的业务,可以通过全局替换 tiny-selecttiny-base-select 来实现性能优化
  • 使用了Select组件下拉树功能的业务,可以通过全局替换 tiny-selecttiny-tree-select 来实现性能优化
  • 使用了Select组件下拉表格功能的业务,可以通过全局替换 tiny-selecttiny-grid-select 来实现性能优化
  • 如果业务同时使用了下拉树和下拉表格功能,则可以使用 SelectWrapper 组件

场景示例

仅使用base-select与select组件打包对比包体积减少50%以上

新增功能:懒加载支持

tree-select 现在支持懒加载,想象一下,一个包含 10,000 个节点的树形选择器,以前需要一次性加载所有数据,现在可以按需加载,性能提升不是一点点!

懒加载的使用场景

  1. 大数据量树形结构 - 当树节点数量超过 1000 个时,懒加载可以显著提升性能
  2. 动态数据加载 - 数据需要从服务器按需获取
  3. 减少初始加载时间 - 只加载用户需要查看的节点

主题动画:一键定制,随心所欲

全局动画配置

为 TinyVue 提供 全局动效配置能力,基于 LESS 与 CSS 变量,实现以下目标:

  1. 统一管理:所有动效集中维护,避免分散定义与重复工作。
  2. 全局可控:通过 CSS 变量统一控制动效的持续时间、延迟、速度等参数。
  3. 组件集成:组件可直接调用统一的动效类名或 @keyframes
  4. 动态可调:通过覆盖 CSS 变量即可在不同场景下切换动效风格。

全局变量定义

/packages/theme/src/base/vars.less 中统一定义动效变量:

:root {
  /* 蚂蚁线相关配置 */
  --tv-motion-ants-shift: 8px;
  --tv-motion-ants-speed: 0.8s;

  /* 其他动效参数... */
}

开发者可在组件主题文件中覆盖这些变量:

.copyed-borders {
  --tv-motion-ants-shift: 12px;
  --tv-motion-ants-speed: 1.2s;
}

也可通过在 /packages/theme/src/base/ 下创建 motion-theme.less 来切换全局动效风格:

:root {
  --tv-motion-ants-shift: 12px;
  --tv-motion-ants-speed: 1.2s;
}

动效分类与目录结构

所有动效存放在 /packages/theme/src/motion/ 目录下,按类型拆分:

motion/
  ├─ fade.less        // 淡入淡出
  ├─ slide.less       // 滑动
  ├─ zoom.less        // 缩放
  ├─ rotate.less      // 旋转
  ├─ bounce.less      // 弹跳
  ├─ scroll.less      // 滚动
  ├─ stroke.less      // 描边
  ├─ shine.less       // 闪烁
  ├─ ants.less        // 蚂蚁线
  ├─ arrow.less       // 箭头
  ├─ tab.less         // Tab 切换
  ├─ progress.less    // 进度条
  └─ index.less       // 统一引入

动效示例

1. 淡入淡出 (fade.less)

@keyframes fade-in {
  0%   { opacity: 0; }
  100% { opacity: 1; }
}

@keyframes fade-out {
  0%   { opacity: 1; }
  100% { opacity: 0; }
}

组件调用示例:

.@{fade-prefix-cls} {
  &-enter-active {
    animation: var(--tv-motion-fade-speed) fade-in ease-out both;
  }
  &-leave-active {
    animation: var(--tv-motion-fade-speed) fade-out ease-in both;
  }
}

2. 滑动 (slide.less)

@keyframes slide-left-in {
  0%   { opacity: 0; transform: translateX(var(--tv-motion-slide-offset-left)); }
  50%  { opacity: var(--tv-motion-slide-opacity-mid); transform: translateX(var(--tv-motion-slide-offset-left-mid)); }
  100% { opacity: 1; transform: translateX(0%); }
}

@keyframes slide-left-out {
  0%   { opacity: 1; transform: translateX(0%); }
  50%  { opacity: var(--tv-motion-slide-opacity-mid); transform: translateX(var(--tv-motion-slide-offset-left-mid)); }
  100% { opacity: 0; transform: translateX(var(--tv-motion-slide-offset-left)); }
}

组件调用示例:

.drawer-slide-left-enter-active {
  animation: slide-left-in var(--tv-motion-slide-speed) linear;
}
.drawer-slide-left-leave-active {
  animation: slide-left-out var(--tv-motion-slide-speed) linear;
}

3. 蚂蚁线 (ants.less,可配置)

@keyframes ants-x {
  0%   { background-position: 0 0; }
  100% { background-position: var(--tv-motion-ants-shift, 8px) 0; }
}

@keyframes ants-x-rev {
  0%   { background-position: 0 0; }
  100% { background-position: calc(-1 * var(--tv-motion-ants-shift, 8px)) 0; }
}

组件调用示例:

.@{grid-prefix-cls}-copyed-borders {
  --tv-motion-ants-shift: 13px;

  .@{grid-prefix-cls}-border-top {
    animation: ants-x var(--tv-motion-ants-speed) linear infinite;
  }
  .@{grid-prefix-cls}-border-right {
    animation: ants-y var(--tv-motion-ants-speed) linear infinite;
  }
  .@{grid-prefix-cls}-border-bottom {
    animation: ants-x-rev var(--tv-motion-ants-speed) linear infinite;
  }
  .@{grid-prefix-cls}-border-left {
    animation: ants-y-rev var(--tv-motion-ants-speed) linear infinite;
  }
}

组件集成方式

  1. 全局引入 所有 @keyframestransition.lessmotion/* 中集中维护,统一加载。
  2. 局部调用 组件可通过 classNameanimation 调用指定动效。
  3. 可配置参数 开发者可通过覆盖 :root 变量调整动效时长、速度等参数。

四、其他重要更新

下拉菜单右键支持

dropdown 组件现在支持右键菜单触发了!这对于需要上下文菜单的场景非常有用。

使用场景

右键菜单在很多业务场景中都非常常见:

  • 表格行操作 - 在表格行上右键显示操作菜单
  • 文件管理 - 文件列表的右键菜单
  • 编辑器 - 文本编辑器的上下文菜单
  • 图形界面 - 画布元素的右键菜单

支持的触发方式

  • click - 点击触发(默认)
  • hover - 悬停触发
  • contextmenu - 右键触发(新功能)
  • focus - 聚焦触发

Switch 组件宽度自定义

switch 组件现在支持自定义宽度了!不再局限于固定的尺寸。

使用场景

自定义宽度让你可以:

  • 适配不同设计风格 - 根据 UI 设计调整开关大小
  • 提升视觉层次 - 通过不同尺寸区分重要程度
  • 响应式设计 - 在不同屏幕尺寸下使用不同宽度
  • 样式定制 - 配合 CSS,你可以进一步定制开关的样式

Modal 头部拖拽

modal 组件现在支持设置 headerDragable 属性,让用户可以拖拽弹窗头部来移动弹窗位置。

使用场景

拖拽功能特别适合:

  • 多窗口场景 - 用户可以自由调整弹窗位置,避免遮挡
  • 大屏幕应用 - 在宽屏显示器上,拖拽可以提升操作效率
  • 用户个性化 - 让用户按照自己的习惯摆放弹窗

注意事项

  • 拖拽功能只在弹窗未全屏时生效
  • 拖拽范围受视口限制,不会拖出屏幕
  • 可以通过 CSS 自定义拖拽时的样式

Drawer 按 ESC 关闭

drawer 组件现在支持通过按 ESC 键关闭,用户体验更加友好。

使用场景

ESC 键关闭是用户习惯的操作方式:

  • 符合用户预期 - 大多数应用都支持 ESC 关闭
  • 提升操作效率 - 键盘操作比鼠标点击更快
  • 无障碍支持 - 方便键盘用户操作

其他关闭方式

Drawer 组件支持多种关闭方式:

  • 点击遮罩层关闭(默认)
  • 点击关闭按钮
  • 按 ESC 键关闭(新功能)
  • 调用 close() 方法

Tree Menu 节点点击增强

tree-menu 组件现在支持在文档中点击添加节点,交互更加直观。

使用场景

这个功能特别适合:

  • 可视化编辑 - 在文档中直接点击添加节点
  • 快速操作 - 提升节点添加的效率
  • 直观交互 - 所见即所得的编辑体验

Guide 组件触发条件优化

guide组件现在支持showStep属性,只有在showSteptrue 时才会触发引导。

使用场景

这个优化让你可以:

  • 条件触发 - 只在特定条件下显示引导
  • 避免干扰 - 不会在用户不需要时弹出
  • 灵活控制 - 根据业务逻辑动态控制引导显示

五、结语

TinyVue v3.28.0 版本的发布,实现了多项重要升级:对选择器组件家族进行了彻底重构,解耦了 Tree / Grid 等重型功能,显著降低了单个组件的体积;新增了全局主题动画配置,让动画效果可通过 CSS 变量随意定制;引入了懒加载、右键菜单、宽度自定义、弹窗拖拽、ESC 关闭等实用功能,进一步提升了开发体验和用户交互;同时修复了 65+ 个 Bug,整体稳定性大幅提升。通过这些改进,TinyVue 不仅在性能上实现了突破,也为开发者提供了更灵活、可维护的组件库,期待在未来的项目中为你带来更高效、更优雅的开发体验,让我们一起,让前端开发变得更简单、更高效!

关于OpenTiny

欢迎加入 OpenTiny 开源社区。添加微信小助手:opentiny-official 一起参与交流前端技术~
OpenTiny 官网:opentiny.design
OpenTiny 代码仓库:github.com/opentiny
TinyVue源码:github.com/opentiny/ti…

欢迎进入代码仓库 StarTinyVue、TinyEngine、TinyPro、TinyNG、TinyCLI、TinyEditor 如果你也想要共建,可以进入代码仓库,找到 good first issue标签,一起参与开源贡献~

本站提供的所有下载资源均来自互联网,仅提供学习交流使用,版权归原作者所有。如需商业使用,请联系原作者获得授权。 如您发现有涉嫌侵权的内容,请联系我们 邮箱:alixiixcom@163.com