本文由体验技术团队TinyVue项目组原创。
一、前言
我们非常高兴地宣布,最近,TinyVue发布了 v3.28.0🎉,
这个版本带来了:
- 选择器组件家族全面重构 - 统一架构,性能提升
- 主题动画全局配置- 一键定制,随心所欲
- 65+Bug 及优化修复 - 稳定性大幅提升
详细的 Release Notes 请参考:https://github.com/opentiny/tiny-vue/releases/tag/v3.28.0
本次版本共有 11 位贡献者参与开发,其中 IKEYCY / neostfox 是新朋友,欢迎新朋友的加入👏,感谢新老朋友们对 TinyVue 的辛苦付出👏
- IKEYCY- 新增贡献者✨
- neostfox- 新增贡献者✨
- shenjunjian
- kagol
- zzcr
- gimmyhehe
- Davont
- discreted66
- wuyiping0628
- James-9696
- gausszhou
同时,如果你在使用过程中遇到任何问题,或者有好的建议,欢迎:
二、升级指南
你可以更新 @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 项目,对比下不同情况下构建产物体积情况:

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

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

可以看到:
- 只引入 Select 组件,产物里面却同时包含了 tree/grid 两个组件,导致产物体积很大
- Area 组件本身只是一个很简单的组件,由于引入了 Select,导致产物体积也非常大
重构目标
本次重构主要达成以下目标:
- 从 Select 组件中**剥离 Tree / Grid 组件,让业务在单引Select组件时不再包含 tree/grid 两个重型组件
- 减少业务单引Select组件(包括TinyVue组件中依赖了Select的组件)时的包体积,优化性能
- 重构完不能引起破坏性变更,不能影响现有业务
重构方案
为了达成以上目标,我们设计并实行了以下重构方案:
- 开发一个新组件 BaseSelect,这个组件和 Select 组件的api和功能完全一致,只是移除了 tree/grid 相关api和功能
- BaseSelect 组件增加panel插槽 ,并设计好panel与reference的沟通机制,让用户可以在panel插槽放置任意内容,包括tree/grid等组件,从而实现下拉树、下拉表格等功能
- 基于 BaseSelect 封装 TreeSelect 组件,实现下拉树组件
- 基于 BaseSelect 封装 GridSelect 组件,实现下拉表格组件
- 重构 Select,移除原有的 tree/grid 功能,基于 BaseSelect / TreeSeelct / GridSelect 组件进行封装,全新的 Select 组件api和功能与原来的Select组件一模一样,不影响用户使用
- 开发全新select-wrapper包装器,包含原本select所有功能用于平替
重构后组件关系如下图:

业务性能优化
使用了 Select 组件的业务,如果想要优化性能,可以:
- 只需要Select基本功能的业务,可以通过全局替换
tiny-select 为 tiny-base-select 来实现性能优化
- 使用了Select组件下拉树功能的业务,可以通过全局替换
tiny-select 为 tiny-tree-select 来实现性能优化
- 使用了Select组件下拉表格功能的业务,可以通过全局替换
tiny-select 为 tiny-grid-select 来实现性能优化
- 如果业务同时使用了下拉树和下拉表格功能,则可以使用 SelectWrapper 组件
场景示例
仅使用base-select与select组件打包对比包体积减少50%以上

新增功能:懒加载支持
tree-select 现在支持懒加载,想象一下,一个包含 10,000 个节点的树形选择器,以前需要一次性加载所有数据,现在可以按需加载,性能提升不是一点点!
懒加载的使用场景
- 大数据量树形结构 - 当树节点数量超过 1000 个时,懒加载可以显著提升性能
- 动态数据加载 - 数据需要从服务器按需获取
- 减少初始加载时间 - 只加载用户需要查看的节点
主题动画:一键定制,随心所欲
全局动画配置
为 TinyVue 提供 全局动效配置能力 ,基于 LESS 与 CSS 变量,实现以下目标:
- 统一管理:所有动效集中维护,避免分散定义与重复工作。
- 全局可控:通过 CSS 变量统一控制动效的持续时间、延迟、速度等参数。
- 组件集成 :组件可直接调用统一的动效类名或
@keyframes。
- 动态可调:通过覆盖 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;
}
}

组件集成方式
- 全局引入 所有
@keyframes 在 transition.less 与 motion/* 中集中维护,统一加载。
- 局部调用 组件可通过
className 或 animation 调用指定动效。
- 可配置参数 开发者可通过覆盖
: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属性,只有在showStep为true 时才会触发引导。

使用场景
这个优化让你可以:
- 条件触发 - 只在特定条件下显示引导
- 避免干扰 - 不会在用户不需要时弹出
- 灵活控制 - 根据业务逻辑动态控制引导显示
五、结语
TinyVue v3.28.0 版本的发布,实现了多项重要升级:对选择器组件家族进行了彻底重构,解耦了 Tree / Grid 等重型功能,显著降低了单个组件的体积;新增了全局主题动画配置,让动画效果可通过 CSS 变量随意定制;引入了懒加载、右键菜单、宽度自定义、弹窗拖拽、ESC 关闭等实用功能,进一步提升了开发体验和用户交互;同时修复了 65+ 个 Bug,整体稳定性大幅提升。通过这些改进,TinyVue 不仅在性能上实现了突破,也为开发者提供了更灵活、可维护的组件库,期待在未来的项目中为你带来更高效、更优雅的开发体验,让我们一起,让前端开发变得更简单、更高效!
关于OpenTiny
欢迎加入 OpenTiny 开源社区。添加微信小助手:opentiny-official 一起参与交流前端技术~
OpenTiny 官网:https://opentiny.design
OpenTiny 代码仓库:https://github.com/opentiny
TinyVue源码:https://github.com/opentiny/tiny-vue
欢迎进入代码仓库 Star🌟TinyVue、TinyEngine、TinyPro、TinyNG、TinyCLI、TinyEditor
如果你也想要共建,可以进入代码仓库,找到 good first issue标签,一起参与开源贡献~