为何我决定放弃使用 element-plus?

发表时间: 2023-09-23 16:14

我在 Vue 2 时代就在使用 element-ui,到了 Vue 3 时代我将它的官方 Vue 3 版本 element-plus 作为我的首选 UI 库。

我曾发布 tailwind-extensions 和
unocss-preset-element-plus 两个包,方便将 element-plus 和 tailwindcss、unocss 结合起来使用。我还给 element-plus 提过两个 PR #12549 和 #14062,提高了 FormRules 类型质量。

element-plus 一直都是我快速开发的好伙伴。但最近面对各种业务或奇葩或实际的需求,我发现 element-plus 有些地方不能很好地满足我的需要。

API 设计

基于我个人代码审美主观来说,我认为 element-plus 某些 API 设计不够统一,给我带来了割裂感。


如果我有以下一组数据,每个元素中的 name 作为文本显示,而 value 作为值被实际使用。

const data = [  { name: 'A', value: 1 },  { name: 'B', value: 2 },  { name: 'C', value: 3 },];

如果我需要多选,我可以使用 el-checkbox,下面就是一个例子。

<script setup lang="ts">import { ref } from 'vue';import { ElCheckboxGroup, ElCheckbox } from 'element-plus';const data = [  { name: 'A', value: 1 },  { name: 'B', value: 2 },  { name: 'C', value: 3 },];const value = ref<number[]>([]);</script><template>  <el-checkbox-group v-model="value">    <el-checkbox      v-for="item of data"      :key="item.value"      :label="item.value"    >      {{ item.name }}    </el-checkbox>  </el-checkbox-group></template>

这个例子很简单,但是却反映了 1 个不算大但也不算小的问题:label 会被用来作为值,但 label 这个单词本身并没有值的含义,这给我造成了认知混乱。

如果我需要单选,我可以使用 el-radio,下面就是一个例子。

<script setup lang="ts">import { ref } from 'vue';import { ElRadioGroup, ElRadio } from 'element-plus';const data = [  { name: 'A', value: 1 },  { name: 'B', value: 2 },  { name: 'C', value: 3 },];const value = ref<number>();</script><template>  <el-radio-group v-model="value">    <el-radio      v-for="item of data"      :key="item.value"      :label="item.value"    >      {{ item.name }}    </el-radio>  </el-radio-group></template>

el-checkbox 类似,label 也被用来作为值,这同样给我造成了认知混乱。

在选项数量较多时,我可以使用 el-select 来做单选或者多选,下面是一个单选的例子,多选也相差不大。

<script setup lang="ts">import { ref } from 'vue';import { ElSelect, ElOption } from 'element-plus';const data = [  { name: 'A', value: 1 },  { name: 'B', value: 2 },  { name: 'C', value: 3 },];const value = ref<number>();</script><template>  <el-select v-model="value">    <el-option      v-for="item of data"      :key="item.value"      :label="item.name"      :value="item.value"    ></el-option>  </el-select></template>

和上面两个例子不同,label 作为文本,value 作为值,我认为这清晰明确得多。如果都采取 el-select 的 API 设计,对于我来说真的太好了。

我翻查过 element-ui 的文档,发现 element-plus API 设计大部分都跟随前者的 API 设计,我不太确定这里面是否带有历史包袱的因素。

功能支持

主观来说,我认为 element-plus 功能支持可以做得更好。

我曾经接到过一个实际的业务需求,有大概一百多条数据,需要支持多选,多选时需要默认隐藏大部分数据,还需要支持全选、全不选和反选。很自然地,我使用了 el-select,因为 el-select 提供了现成的多选和多选时隐藏大部分数据这两项的支持。

遗憾的是,在支持全选、全不选和反选时我却陷入了僵局:el-select 并没有提供相应的插槽,我没有办法在不修改源码的情况下优雅地将这些操作收纳到 el-select 的下拉菜单中。

最后,我只能将这些操作放到了 el-select 外部的下方,被评价“不好看但能用”

<script setup lang="ts">import { ref } from 'vue';import { ElSelect, ElOption, ElButton } from 'element-plus';const data = Array.from({ length: 100 }).map((_, index) => ({  value: index,  label: index,}));const value = ref<number>();</script><template>  <el-row>    <el-col>      <el-select        v-model="value"        multiple        filterable        collapse-tags        collapse-tags-tooltip      >        <el-option          v-for="item of data"          :key="item.value"          :label="item.name"          :value="item.value"        ></el-option>        <!-- 我想要的 -->        <!-- <template #action>          <el-space>            <el-button text>全选</el-button>            <el-button text>全不选</el-button>            <el-button text>反选</el-button>          </el-space>        </template> -->      </el-select>    </el-col>    <el-col>      <!-- 实际做出来的 -->      <el-space>        <el-button text>全选</el-button>        <el-button text>全不选</el-button>        <el-button text>反选</el-button>      </el-space>    </el-col>  </el-row></template>

如果 el-select 支持 Action Slot 该多好啊!那样我就可以轻轻松松地完成需求了,而且页面也优雅、好看一些。我曾经翻查过 naive-ui 和 ant-design-vue,发现它们都支持这类场景,这让我更希望 el-select 能够增加这个功能了。

但是,添加这个功能支持需要花费大量时间。首先需要创建 Discussion 征询大家的意见,之后需要自己创建 PR 或者等待其他人来实现它。如果创建了 PR,可能需要一两个月的 Code Review,因为 element-plus 的维护者们真的太忙了。PR 合并后,还需要等待正式发版。

小结

简而言之,我认为 element-plus 很棒,但是某些 API 设计不够统一,给我带来了割裂感,功能支持有所欠缺,可以做得更好。在需要快速开发业务需求的场景下,这两方面的缺点被放大了不少,我的前端开发工作进度会因此有所卡顿。

客观来说,要改进这两方面问题并非一朝一夕之事。遗憾的是我没有太多时间参与改进或是等待改进,我现在在尝试 naive-ui 和 ant-design-vue,它们给我的感觉都还不错。衷心希望 element-plus 越来越好,也感谢 element-plus 陪我走过几年前端时光

原文


链接:
https://juejin.cn/post/7281462577116299319