Vue3+TSX手撸Element Tree升级版(vue3.1)
csdh11 2025-05-08 17:33 3 浏览
Vue3开源的Tree组件有很多,大家常用的是以Element Tree为首的UI组件。就我个人体验来说,有些地方做的并不好,尤其是树节点的增删改操作、勾选功能以及高级的拖拽实现。这些功能不能很好的整合在一起,与后台交互的可扩展性也比较差。翻开element plus tree的源码,你会发现有很多的设计思路比较受限,实现的很繁琐。毕竟vue3给我们提供非常便利的Composition API,组件各部分功能的开发可以更好的进行模块化、数据响应式编程以及功能整合。 个人在尝试手撸Tree组件时,有深刻的体会,利用vue3提供的特性加上一些突破性的设计,在很好仿element tree实现各项功能的同时,代码量可以缩减到1/3。因此,个人觉得很有必要把自己的学习心得跟大家分享下。 Tree组件还在迭代开发中,本地保留了渐进式开发的练习代码:
添加图片注释,不超过 140 字(可选)
这种练习方式便于我回头整理和总结是如何从0实现一个较为完整的Tree组件的。如果大家关注和反馈比较热烈的话,打算出一套视频教程手把手演示如何一步步实现的。 软件
- Node 18.18.2
- NPM 9.8.1
- VSCode 适合专业的前端
- IntelliJ Idea 更适合以Java为后端的全栈开发人员,考虑到后续要开发后台做UI组件的交互,这里选该工具
技术栈
- Vite 5.2.0
- Vue 3.4.21
- Typescript 5.4.5
- Eslint 8.57.0
- Prettier 3.2.5
- TailWindcss 3.4.3
- Sass 1.75.0
- ...
这套基本的技术栈个人觉得最适合Vue3组件库的研发,同时组件的编写形式也将由传统的.vue单文件结构,切换到tsx的模板与脚本混合的自由模式。后续还会引入VitePress来实现组件示例的文档可视化。 项目结构
添加图片注释,不超过 140 字(可选)
迭代复盘
工程整合阶段
快速搭建Vite脚手架
安装全局工具:npm i -g vite。快速初始化一个整合好ts的vue3工程,使用命令npm init vite,后续用交互式命令执行选项来创建。运行一个小而美的应用:
添加图片注释,不超过 140 字(可选)
回归最简配置
忘掉一切招式,一切从头开始,进行最简化配置,在这个基础上一点点叠加。编写一个最简单的.vue单文件的HelloWorld组件并应用一下:
添加图片注释,不超过 140 字(可选)
集成jsx vite和jsx的集成非常简单,只要装一个插件并在vite.config.js中配置下即可。然后把组件的.vue文件改造成.jsx来实现,jsx的模板写法有点像早年Java后端jsp中混杂java脚本,模板渲染的写法更自由。练习:将前面的组件改写成jsx的实现方式,要求功能保持不变。 集成ts 在前一节基础上,完成vite和ts的整合。
- 加ts依赖以及和vue整合的tsc编译器依赖
- tsconfig相关的配置文件
- 改写js和jsx文件
- vite的dev启动服务中增加tsc的编译命令 注意以下问题的修复:
添加图片注释,不超过 140 字(可选)
练习:试着将HelloWorld组件中字符串的msg改为一个包含info字符串的IMsg接口类型,并改造前面的示例
集成eslint和prettier
涉及的整合步骤列了一个大纲,可以照着去做
添加图片注释,不超过 140 字(可选)
踩坑:vite-plugin-eslint插件配置的ts编译问题
集成tailwindcss
方便组件样式的应用,大部分情况不用自己手写样式,复用tailwindcss的样式,提高开发和工程构建效率:
添加图片注释,不超过 140 字(可选)
练一练:试着为HelloWorld组件中的msg标题应用下tailwindcss样式
添加图片注释,不超过 140 字(可选)
Tree组件基础开发
扁平结构的处理和树渲染
本节目标:实现一个扁平结构的列表数据下Tree的页面渲染:
添加图片注释,不超过 140 字(可选)
难点:如何将原始嵌套结构的数据拍平为扁平化的数据
收益:
- 数组reduce方法在递归处理中的应用。
- tsx中v-for的写法,注意key的绑定
树节点的展开与折叠交互
实现效果:
添加图片注释,不超过 140 字(可选)
开发要点:
- 节点类型的定义与扩展
- 扁平化函数改造:原始节点类型转扁平化节点类型
- 扁平化数据列表的动态渲染
- 使用ref和computed实现可见列表的响应式渲染
- 通过onClick交互事件改变节点的expanded属性来触发视图的更新,注意是局部更新
难点:
- 可见列表过滤的思路
- 如何确定一个扁平化节点下有多少个后代子元素,有没有更好的办法
计算属性在树结构中的妙用 该部分是本套教程的重点章节之一,也是后续Tree组件高级功能实现的基础。不使用计算属性,程序功能实现会变得越来越困难,且执行性能越来越低。 计算节点索引和后代节点长度 Tree很多功能实现需要定位当前索引的位置以及子节点,如果每次都手动遍历整个扁平数据列表,不但low而且性能不高。本节教你怎么在ts中实现响应式的数据计算属性。用了计算属性,它会缓存计算结果,当关注的数据发生变化才会重新计算,执行效率也提高了。 实现效果:
添加图片注释,不超过 140 字(可选)
这里显示了扁平化数据列表每个节点的索引,当节点个数发生改变,位置受影响的节点会重新计算(后续新增删除节点时会演示)。同时在控制台看到,子节点长度计算属性第一次触发后会缓存结果,数据没变化时不会重新计算。 思路和实现:略 实现参照线 在上一节基础上,继续扩展结构化节点计算属性,实现参照线长度计算属性,以便随着节点的展开折叠动态生成参照线的高度,看效果:
添加图片注释,不超过 140 字(可选)
绿色数字动态展示了父节点参照线的长度。 节点和参照线过渡动画 本节会对之前实现的生硬的折叠和展开效果增加动画修饰,会综合运用Vue对于节点渲染所支持的动画特性,包括:
- <TransitionGroup>、<Transition>过渡动画标签的使用
- 编写scss文件实现过渡动画样式控制
- 应用onBeforeEnter、onEnter以及onLeave的动画钩子加dom样式操作,更精准的控制vue内层元素渲染的动画效果
实现难度在于,线的高度是动态计算出来的,且线的元素位于循环渲染的节点元素的内部,需要手动处理vue过渡动画失效的情况。 实现效果,过渡动画时间调大,方便看效果:
添加图片注释,不超过 140 字(可选)
svg图标组件的封装与使用
算是复习下.vue单文件组件的开发,整合iconfont的免费素材库js文件,通过自定义组件标签的形式来使用各个svg小图标。
我们用svg小图标替换掉原先<button>标签的+、-符号,看效果:
添加图片注释,不超过 140 字(可选)
Tree高级功能实现
自定义节点图标和操作插槽
本节介绍如何快速实现tsx中的slots,看效果:
添加图片注释,不超过 140 字(可选)
tsx的App组件中使用tree组件时指定插槽的方式:
return () => {
const flatTree = generateFlatTree(treeData)
return (
<div class='m-4'>
<FxTree data={flatTree}>
{{
icon: (node: IFlatTreeNode) => (
<span class='mr-1'>
{/*{!node.isLeaf ? (*/}
{/* <svg-icon icon='folder-fill' class={'inline-block h-[18px] w-[20px] fill-orange-500'} />*/}
{/*) : (*/}
{/* <svg-icon icon='folder-fill' class={'inline-block h-[18px] w-[20px] fill-gray-400'} />*/}
{/*)}*/}
<svg-icon icon='folder-fill' class={`inline-block h-[18px] w-[20px] ${!node.isLeaf ? 'fill-orange-500' : 'fill-gray-400'} `} />
</span>
),
operation: () => (
<div>
<svg-icon icon='add' class={'inline-block h-[20px] w-[20px] cursor-pointer fill-pink-500'} />
<svg-icon icon='edit' class={'ml-4 inline-block h-[20px] w-[20px] cursor-pointer fill-green-500'} />
<svg-icon icon='delete' class={'ml-4 inline-block h-[20px] w-[20px] cursor-pointer fill-slate-500'} />
</div>
)
}}
</FxTree>
</div>
)
}
扁平化tree的前端分页
在数据量很大的情况下,前端tree的渲染会变慢,可以采用懒加载或者咱独创的扁平化分页的形式来提高访问效率。这种前端分页咱们甚至可以支持跨页勾选:
添加图片注释,不超过 140 字(可选)
Tree的使用方式:
添加图片注释,不超过 140 字(可选)
新增子节点
目前只实现了在父节点下新增子节点,新增一级节点其实更简单,后续会完善,包括与后台的数据交互,目前主要实现前端用户交互功能。
新增效果:
添加图片注释,不超过 140 字(可选)
很显然,因为前面我们用计算属性对节点基础功能做了很好的铺垫,实现新增节点变得非常简单。看到新增节点后,受影响的节点的索引和参照线长度都会重新计算。
组件的使用:
添加图片注释,不超过 140 字(可选)
删除节点
移除节点也非常简单,不需要对树进行遍历,使用前面实现的节点索引和长度的计算属性即可,在原始结构和扁平结构中删除并重新绑定后续节点的前置节点即可。效果:
添加图片注释,不超过 140 字(可选)
使用方式,后续需要优化,在用户api重构章节教大家如何优化哈:
添加图片注释,不超过 140 字(可选)
节点重命名
添加图片注释,不超过 140 字(可选)
新增的节点可以立即开启编辑,该功能是组件内置的,使用组件时可这样开启:
添加图片注释,不超过 140 字(可选)
节点勾选
节点勾选的功能可以很好和新增删除节点结合,这点超越了element tree,看效果:
添加图片注释,不超过 140 字(可选)
还支持在启用前端分页时的跨页勾选:
添加图片注释,不超过 140 字(可选)
节点数据懒加载
该功能会与后台接口交互,这里我们约定接口属性有一个noData字段如果是true则是叶子数据节点,不会触发懒加载。懒加载一次后,再展开则不会再加载数据;同时该功能可以很好的和节点的新增、编辑、删除以及节点勾选功能很好的工作。效果如下:
添加图片注释,不超过 140 字(可选)
节点拖拽
该功能目前开发了一半,因为有了前面基础功能的铺垫,实现拖拽会非常简单,这比element plus tree的实现代码将近少了1/3。具体细节,咱们会在后续系列教程中教大家怎么实现。先看半成品效果:
添加图片注释,不超过 140 字(可选)
咱们实现的效果,对比element tree,发现拖拽过程中光标也不会闪来闪去,用户体验很棒,剩下还要实现拖放后的节点更新操作。效果会后续更新。。。 总结 关于前端组件自己造轮子的教程,能比较完整的把各部分实现的细节都以逐步迭代的形式连载下来的不是很多。包括一些视频教程,所谓的前端技术专家教你手写vue组件,虎头蛇尾的情况会比较多,这类教程入个门就行,学会怎么搭建环境、整合工具、组件开发流程,语言基础的东西自己补补,剩下就是设计实现思路、api特性的灵活运用。最后这部分是该类教程成功的关键。掘金前端大佬前端杨村长这方面的教程给我的启发很大,用大佬自己的话来说,教会我的东西,算是“抛砖引玉”。实际我学到的东西,不光是语法、框架特性,更多是设计上的思考,如怎么把树的递归渲染做成简单的列表渲染,怎么用计算属性来代替人工的节点遍历,Vue Composition API对复杂组件开发的代码重构带来哪些优势,等等。。。最后,我想说的是,造轮子这件事,不用参考现成UI的源码实现,毕竟开源源码都是众多大佬业余精力奉献出来的,设计思路上会有很多可以优化的部分,主要还是奔着用户的使用和期待,以实现功能为主。咱更多应该站在产品和API用户的角度,再结合知识储备,让设计和实现能结合Vue新特性,简化开发任务,提高效率和代码质量。大家加油!!
相关推荐
- IDEA界面太丑??尝试一下这几个插件
-
前言IntelliJIDEA主要用于支持Java、Scala、Groovy等语言的开发工具,同时具备支持目前主流的技术和框架,擅长于企业应用、移动应用和Web应用的开发。IntelliJi...
- 小巧 Vue 页面滚动进度条组件ScrollProgress
-
今天给大家分享一个轻量级Vue.js全屏滚动进度条组件VueScrollProgress。vue-scroll-progress一款基于vue.js构建的页面滚动进度条组件,...
- 基于vue实现可视化拖拽编辑器,页面生成工具,提升前端开发效率
-
项目介绍基于vue实现的可视化拖拽编辑器,实现页面生成工具,提升前端开发效率。可以基层到移动端项目作为自定义json直接生成UI页面。项目特点功能特点...
- 优秀 vue+heyui 后端管理系统HeyUI-Admin
-
今天再给小伙伴们推荐一款成熟的企业中后台管理系统HEYUI-Admin。heyui-admin基于vue.js和heyui组件库构建的后台管理系统。包含基础表单/表格功能,拓展组件(图表、富文本编辑...
- 响应式 Vue.js 前端组件化框架Xvue-UI
-
今天给小伙伴们推荐一款超不错的Vue轻量级组件框架XVueUI。xvue-ui基于vue2.x构建的响应式前端组件化框架。轻量级、易于上手,提供...
- 《基于SpringBoot+Vue的在线视频系统设计与实现》开题报告
-
【计算机毕业设计案例】基于SpringBoot+Vue的在线视频系统设计与实现_哔哩哔哩_bilibili...
- 超好用 Vue.js 图片裁切组件Vue-ImgCutter
-
今天给小伙伴们分享一个超棒的Vue图片任意裁剪插件VueImgCutter。vue-img-cutter基于vue2.x构建的轻量级剪切图片组件。支持移动图像、放大缩小图片、任意移动图片、固定比...
- Vue 3 进阶用法:异步组件(vue 异步组件原理)
-
一、代码分割一个大型前端应用,如果所有代码都放在单一文件,体积会特别大,下载时间长,白屏时间久,用户体验差。...
- 源码补丁神器—patch-package(源码助手怎么用)
-
作者:张浩一、背景vue项目中使用vue-pdf第三方插件预览pdf,书写业务代码完美运行,pdf文件内容正常预览无问题。后期需求有变,业务需求增加电子签章功能。这个时候pdf文件的内容可以显示出...
- 经验分享:Vue2 项目升级 Vue3 + Element Plus,借助Deepseek手动升级
-
Vue3出来好久了,我开发的项目还在使用Vue2框架,一般情况下不考虑升级,但是最近需要接入工作流程引擎之类的,看了下Vue2生态下操作空间不是很好,那索性尝试升级Vue3吧。一番操作下来,升级成功,...
- 34K Star!史上最全JavaScript资源库 awesome-javascript
-
34KStar!史上最全JavaScript资源宝库大揭秘引言在GitHub上,有一个备受瞩目的JavaScript资源仓库,以其全面的内容和精心的分类,成为了众多开发者的必备参考。这个拥有超过...
- 基于 Vue.js 磁片栅格布局组件VueGridLayout
-
#头条创作挑战赛#今天给大家分享一个超优秀的vue.js拖拽栅格布局插件VueGridLayout。...
- 6款高颜值 Vue3 PC端UI组件库(vue3开发组件库)
-
马上到国庆了,还没学习或者想学习vue3的小伙伴们有安排上没?这次推荐几个比较流行的VUE3UI组件库,合理利用,又或者学习借鉴都是不错的选择。1、element-pluselement-plus...
- 高性能 vue.js+ztree 树形组件Vue-GiantTree
-
今天给大家分享一款超棒的Vue海量数据渲染树形组件VueGiantTree。vue-giant-tree基于ztree封装的Vue树形组件。轻松实现大数据高性能渲染,适合海量数据渲染场景。zTr...
- 【推荐】2024年推荐的6款开源免费 Vue 后台管理系统模板,建议收藏
-
前言在现今的软件开发领域,...
- 一周热门
- 最近发表
-
- IDEA界面太丑??尝试一下这几个插件
- 小巧 Vue 页面滚动进度条组件ScrollProgress
- 基于vue实现可视化拖拽编辑器,页面生成工具,提升前端开发效率
- 优秀 vue+heyui 后端管理系统HeyUI-Admin
- 响应式 Vue.js 前端组件化框架Xvue-UI
- 《基于SpringBoot+Vue的在线视频系统设计与实现》开题报告
- 超好用 Vue.js 图片裁切组件Vue-ImgCutter
- Vue 3 进阶用法:异步组件(vue 异步组件原理)
- 源码补丁神器—patch-package(源码助手怎么用)
- 经验分享:Vue2 项目升级 Vue3 + Element Plus,借助Deepseek手动升级
- 标签列表
-
- mydisktest_v298 (34)
- document.appendchild (35)
- 头像打包下载 (61)
- acmecadconverter_8.52绿色版 (39)
- word文档批量处理大师破解版 (36)
- server2016安装密钥 (33)
- mysql 昨天的日期 (37)
- parsevideo (33)
- 个人网站源码 (37)
- centos7.4下载 (33)
- mysql 查询今天的数据 (34)
- intouch2014r2sp1永久授权 (36)
- 先锋影音源资2019 (35)
- jdk1.8.0_191下载 (33)
- axure9注册码 (33)
- pts/1 (33)
- spire.pdf 破解版 (35)
- shiro jwt (35)
- sklearn中文手册pdf (35)
- itextsharp使用手册 (33)
- 凯立德2012夏季版懒人包 (34)
- 冒险岛代码查询器 (34)
- 128*128png图片 (34)
- jdk1.8.0_131下载 (34)
- dos 删除目录下所有子目录及文件 (36)