Vue拖拽库断代,别再浪费时间卷组件库了!

发表时间: 2023-10-16 17:20

前言

最近在测试 Tailwind CSS 和 Uno CSS 这两种原子化 CSS 工具是否能够有效减少打包后的文件体积时,先开始分析这些工具的优缺点,然后再直接上数据,最后做了一款经典的 TodoList 来进行测试,文章都写好了就差最后的数据了:

但测试得出来的结果相差很小,几乎没有什么太大的参考价值。想想也是,一个 TodoList 刚能有几行样式?只有在样式足够庞大的前提下这个测试才有意义,毕竟样式多了重复的部分自然也会变多,然后积少成多最终才能达到量变引起质变的效果。当然量变引起质变这个说法可能稍微夸张了点,但样式越庞大得出来的结果才越有参考价值这个肯定是没错的,于是我把原本比较简陋简洁的 TodoList 来了个大升级:

但就在给列表拖拽排序的时候我发现了一个令人难以接受的事实,说到 Vue3 拖拽库大家首先想到的是哪个?是 VueDraggable 对吧?那其次呢?假如 VueDraggable 停止维护了,并且随着 Vue 的升级也慢慢无法兼容了,大家首先想到的替代品是什么?替代品就是 Vue3 这么庞大的生态居然没有任何一款成熟的替代品!

测试原子化 CSS 时的发现

本来想着测试如下几种情况:

  • Vue 3 只用 Tailwind 写一个 TodoList
  • Vue 3 只用 UnoCSS 的属性模式写一个 TodoList
  • Vue 3 复杂样式用普通写法、简单样式用 Tailwind 写一个 TodoList
  • Vue 3 复杂样式用普通写法、简单样式用 UnoCSS 的属性模式写一个 TodoList
  • Vue 3 不用任何原子化 CSS 写一个 TodoList
  • Vue 3 不用任何原子化 CSS(但用内置的 scoped)写一个 TodoList
  • Vue 3 只用 CSS Module 写一个 TodoList

然后分别再用 Vite 和 Webpack 进行打包,观察一下哪种情况下的尺寸是最优的,又到底能不能拉开比较大的差距。先用 yarn create vue 创建了一个项目,后来想给列表加个排序功能,首先想到的无非就是那一个仅有的选择:VueDraggable。但万万没想到控制台一直报错,然后列表也无法被拖动:

一开始我还以为是自己哪写错了,但按照官网示例一行行看下来也没发现哪写错了呀?干脆把官方示例直接复制下来粘贴到项目里,没想到还是报一样的错。这回我有点明白了:不是我自己写错了,而是 VueDraggable 太长时间没维护,Vue 升级到 3.3 之后就开始无法兼容了。

为了验证这个猜想,我把 Vue 降级到 3.2,结果 Vite 给报了这样一个错:

>=3.2.25 是吧?那就 yarn add vue@3.2.25,在一行代码都没改的情况下居然成功运行了:

不过依然还是有 bug,比如说无法成功换顺序,检查多遍也看不出哪写错了,并且控制台也未能给出任何报错:

那就继续降级试试,降级到 3.2.13,这回有报错了:

再降级到 3.2.0,但降不下去了居然:

之前用 Vite 创建的那个项目就报这个错,所以我用 @vue/cli 又新建了一个项目,但万万没想到居然还报相同的错,奇怪,@vue/cli 用的不是 webpack 么?在网上搜了下 Vue 报的 $scopedSlots 那个错,发现早就有人遇到过这个错了:

日期是去年八月份,然后经过了一系列测试,发现把 v-model 换成 :list 就好了(指的是 3.2.25,3.3.4 还是不好使):

但还是有问题,感没感觉每次排序的时候好像都多运行了一遍动画,就是排序成功松开鼠标之后,它又会回到原先的位置,然后重新运行了一遍排序动画,可能是把 v-model 换成 :list 导致的。这说明了什么?说明了 Vue3 唯一一款成熟(其实也不太成熟)的拖拽库目前的问题已经很严重了,它已经两三年都没发过新版了:

基本上已经可以算得上是被废弃的库了,并且针对 Vue3 开发的版本一共就 4.0.0、4.0.1、4.0.2、4.0.3、4.1.0 这五个,到现在还都不是主要版本呢,你要是 npm i vuedraggable 的话安装的是 2.x 的版本,2.x 是 Vue2 时代的了,想要安装 4.x 还必须得 npm i vuedraggable@next。

DnD 拖放库

前面说的是拖拽库,主要是拖拽排序库,但即使 VueDraggable 现在依然还在正常维护,Vue 也还是缺一款功能强大的拖放库,到这里有人可能就纳闷了:拖拽和拖放有什么区别?

拖拽一般指的就是列表间的拖拽排序,比方说 VueDraggable 就是基于 SortableJS 上的 Vue 封装适配,Sortable 的就是排序的意思:

而拖放主要是 Drag and Drop 翻译过来的:

虽然在这里面并没有找到放下等字眼,但 drop 就是放下的意思,经常看美剧的朋友肯定都听过这样一句台词:

Drop your gun!

Now!!!

拖放是 H5 的一对 API,它俩的关系有点类似于 mousedown 和 mouseup,有 mousedown 就肯定有 mouseup,有 drag 就肯定有 drop。因为拖是鼠标按下,放是鼠标抬起,总不能一直按着鼠标不放吧?又不是玩马来剑(穿越火线刀战里有个 bug 级武器叫马来剑,这种武器攻击距离非常远,左键技能攻击范围还很广,导致哪怕技术一般的小白级选手只要一直按住左键都能取得不俗的战绩,所以刀战时用马来剑的玩家都会被这句顺口溜讽刺:马来狗马来狗,按住左键不撒手)

拖放(DnD)可就不仅仅只是排序了,比如:

拖都一样,都是被点击的元素跟随鼠标进行移动,但这个例子的放就不一样了,它的放并不是为了排序,而是放在哪该元素就定位在哪。或者是将选中元素放到另外一个容器当中:

或者这种以 drag 为主的:

总之非常灵活,不仅仅只是局限于拖拽排序而已:

但 Vue 就是没有,也不能说没有,只能说没有成熟的,那种零零星星几百的周下载量即使写的再好,看到 GitHub 的那点 Star 数估计也没多少人敢用。所以之前我一直想做一款来填补一下这方面的空白,刚好那阵茹姐(熟悉我的朋友可能知道我是掘金的首批签约作者,签约时对接的是茹姐。签约结束后她希望我能够出一本小册,因为我在她当时的团队内很有名气,大家都爱看我的文章,所以很期待我更进一步的输出)茹姐总是催我做个小册,而我当时又恰好在开发低代码项目,大家知道低代码可是 DnD 的重灾区,毕竟大部分的低代码基本都是通过拖拽的形式来搭建页面的:

我们自然也不例外,但我们公司因为兼容性以及历史等问题采用的是 Vue2 技术栈,低代码是新开的项目,而且面向的用户是公司内部的运营同事,所以不用考虑兼容性问题。于是我大胆的采用了 Vue3 来开发低代码项目,那时候 Vue3 还是挺新鲜的技术呢!刚刚 3.0 没多久,市面上也很少有项目是采用 Vue3 开发出来的,对此我感到非常的兴奋。

不过随着项目的进行,笑容就慢慢的从我脸上消失掉了,因为 Vue3 的生态实在是太匮乏了。不说别的,就说这个拖拽库,能选的仅仅就只有 VueDraggable 这一个,其它的要么就是下载量太低不太靠谱、要么就是只有针对 Vue2 版本的、要么就是更新频率低到让人怀疑作者已经跑路了。而且 VueDraggable 还不是专门为 Vue 开发的,只是在 SortbaleJS 上做了一层针对 Vue 的封装。说实话在项目越来越复杂的情况下这个库真的不好用,而且最要命的是这个库基本上已经停止了维护:

所以当时我特别想趁项目还没变得特别庞大的时候赶紧用 React 来进行重构,但结果可想而知,这一提议惨遭拒绝:我们要保持公司技术栈的一致性,不能这个项目用 Vue、那个项目用 React、下个项目你是不是还想再试试 Angular 啊?

于是乎我的新主题确定了:《从 React DnD 到 Vue DnD》,我准备把 React 比较主流的拖放库 React DnD 移植过来,顺便把它写成小册。茹姐一听我要开始准备筹划小册了很高兴,不过她表示不太清楚这个 DnD 到底是啥意思,我告诉她 DnD 就是 Drag(拖)and(和)Drop(放)的意思。

听完我的解释后茹姐给我来了个灵魂拷问:为什么不是 DaD:

  • Drag
  • and
  • Drop

我说:可能是 DaD 有别的意思怕误会吧:

不过她这么一问确实让我也有点好奇,于是我问了一下我大学同学,他大学毕业后就去了澳洲留学,澳洲毕业后又去了北美工作,常年漂泊在海外,所以我觉得他的英语水平应该是没问题的,如果他也不知道的话就让他帮忙问下外国人,结果他说:在这边我才是外国人…

他说国外喜欢把发音与某些字母相似的单词替换成字母,比方说:

  • you:u
  • I see you:icu
  • thanks:thx
  • okay:ok
  • cue:q
  • through:thru
  • and:n
  • easy:ez(国内常用)

我问他 and 和 n 发音也不相似啊,他说那是因为你单独读不相似,但你把 and 放在句子里读快了就相似了(国外英语都是带连读和略读的,and 读快了的情况下 d 不发音)不信你看爱彼迎的英文 Airbnb:

后来他在看《头号玩家》这部电影时听到了把 and 读成 n 的一个桥段,立马推荐给我听,我听了一下还真是,就是这个桥段:

可惜文章里不能贴视频,不然我把视频片段剪下来给大家听,字幕里显示的是 Me and you,但听起来真的和 Me n u 差不多,所以 and 不是按照首字母来进行缩写的,而是根据读音来进行的缩写,就像 you 的缩写也不是 y 而是 u 一样。


作者:手撕红黑树
链接:
https://juejin.cn/post/7290169619511377976