Element Plus/VXE-Table UI 组件库规范:统一用法实战,避开样式冲突与维护混乱|工程化与协作规范篇

【Element Plus + VXE-Table】实战:从选型规范到落地实操,彻底搞懂组件库高效用法,避开样式冲突、维护混乱等高频坑!

📑 文章目录

  • 一、为什么需要统一规范?
    • [1.1 常见问题](#1.1 常见问题)
    • [1.2 规范能带来什么](#1.2 规范能带来什么)
  • 二、技术选型:什么时候用谁?
    • [2.1 Element Plus 和 VXE-Table 的定位](#2.1 Element Plus 和 VXE-Table 的定位)
    • [2.2 选型决策图(简化版)](#2.2 选型决策图(简化版))
  • [三、Element Plus 使用规范](#三、Element Plus 使用规范)
    • [3.1 按需引入 vs 全量引入](#3.1 按需引入 vs 全量引入)
    • [3.2 全局样式覆盖规范](#3.2 全局样式覆盖规范)
    • [3.3 命名与类名前缀约定](#3.3 命名与类名前缀约定)
  • [四、VXE-Table 使用规范](#四、VXE-Table 使用规范)
    • [4.1 按需引入](#4.1 按需引入)
    • [4.2 复杂表格示例](#4.2 复杂表格示例)
    • [4.3 与 Element Plus 的样式隔离](#4.3 与 Element Plus 的样式隔离)
  • 五、统一封装:减少重复、统一行为
    • [5.1 封装通用表格组件思路](#5.1 封装通用表格组件思路)
    • [5.2 表单封装示例](#5.2 表单封装示例)
  • 六、常见踩坑与解决
    • [6.1 样式不生效](#6.1 样式不生效)
    • [6.2 VXE-Table 与 Element Plus 样式互相覆盖](#6.2 VXE-Table 与 Element Plus 样式互相覆盖)
    • [6.3 按需引入后打包体积仍然偏大](#6.3 按需引入后打包体积仍然偏大)
    • [6.4 表格数据更新但界面不刷新](#6.4 表格数据更新但界面不刷新)
  • 七、工程化落地清单
    • [7.1 项目初始化](#7.1 项目初始化)
    • [7.2 编码约定](#7.2 编码约定)
    • [7.3 文档与协作](#7.3 文档与协作)
  • 八、总结
  • 附录:快速参考
  • [🔍 系列模块导航](#🔍 系列模块导航)
    • [📝 工程化与协作规范](#📝 工程化与协作规范)
    • [📚 系列总览](#📚 系列总览)

同学们好,我是 Eugene(尤金),一名多年中后台前端开发工程师。

(Eugene 发音 /juːˈdʒiːn/,大家怎么顺口怎么叫就好)

很多前端开发者都会遇到一个瓶颈:

代码能跑,但不够规范;功能能实现,但维护起来特别痛苦;一个人写没问题,一到团队协作就各种混乱、踩坑、返工。

想写出干净、优雅、可维护 的专业代码,靠的不是天赋,而是体系化的规范 + 真实实战经验

这一系列《前端规范实战》,我会用大白话 + 真实业务场景,不讲玄学、不堆理论,只分享能直接落地的规范、标准与避坑指南。

帮你从「会写代码」真正升级为「会写优质、可维护、团队级别的代码」。


一、为什么需要统一规范?

1.1 常见问题

  • 样式冲突:多人各写各的,类名、变量、覆盖方式不统一
  • 心智负担 :有的用 el-table,有的用 vxe-table,新人难上手
  • 打包冗余:按需引入不规范,全量引入导致体积过大

[⬆ 返回目录](#⬆ 返回目录)

1.2 规范能带来什么

  • 样式统一、可预期
  • 新成员上手快
  • 减少重复造轮子
  • 降低维护成本

[⬆ 返回目录](#⬆ 返回目录)


二、技术选型:什么时候用谁?

2.1 Element Plus 和 VXE-Table 的定位

场景 推荐 理由
表单、弹窗、按钮、布局 Element Plus 基础组件完备、生态成熟
复杂表格(多选、树、合并、虚拟滚动) VXE-Table 表格能力强
简单表格(列少、无复杂交互) Element Plus el-table 足够用,依赖少

原则:基础表单用 Element Plus,复杂表格用 VXE-Table,简单表格用 el-table

[⬆ 返回目录](#⬆ 返回目录)

2.2 选型决策图(简化版)

Plain 复制代码
需求:需要一个表格
    ↓
是否有以下任一情况?
  - 列很多(>20)需要虚拟滚动
  - 树形数据
  - 复杂合并单元格
  - 可编辑表格、复杂筛选
    ↓
是 → 用 VXE-Table
否 → 用 Element Plus el-table

[⬆ 返回目录](#⬆ 返回目录)


三、Element Plus 使用规范

3.1 按需引入 vs 全量引入

建议:按需自动引入(unplugin-vue-components + unplugin-auto-import)

js 复制代码
// vite.config.js
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'

export default {
  plugins: [
    AutoImport({
      resolvers: [ElementPlusResolver()],
      dts: 'src/auto-imports.d.ts',
    }),
    Components({
      resolvers: [ElementPlusResolver()],
      dts: 'src/components.d.ts',
    }),
  ],
}

效果:组件和 API 无需手动 import,直接使用,且只打包用到的组件。

[⬆ 返回目录](#⬆ 返回目录)

3.2 全局样式覆盖规范

不建议到处写 !important 覆盖,建议集中用 CSS 变量或统一覆盖文件。

css 复制代码
// styles/element-override.scss

// 1. 通过 CSS 变量统一改主题
:root {
  --el-color-primary: #409eff;
  --el-border-radius-base: 4px;
}

// 2. 针对特定组件的覆盖,加项目前缀避免污染
.my-project {
  .el-button--primary {
    border-radius: 8px;
  }
  
  .el-table {
    --el-table-border-color: #e4e7ed;
    --el-table-header-bg-color: #f5f7fa;
  }
}

[⬆ 返回目录](#⬆ 返回目录)

3.3 命名与类名前缀约定

统一使用项目级类名前缀,方便排查样式、避免污染:

html 复制代码
<template>
  <div class="order-page">
    <el-form class="order-page__form" />
    <el-table class="order-page__table" />
  </div>
</template>

<style scoped lang="scss">
.order-page {
  &__form { /* 表单样式 */ }
  &__table { /* 表格样式 */ }
}
</style>

[⬆ 返回目录](#⬆ 返回目录)


四、VXE-Table 使用规范

4.1 按需引入

js 复制代码
// main.js 或 plugins/vxe-table.js
import { createApp } from 'vue'
import App from './App.vue'

// 按需引入 VXE-Table
import VXETable from 'vxe-table'
import 'vxe-table/lib/style.css'

// 如果用到表单等扩展
// import VxeTablePluginElement from 'vxe-table-plugin-element'
// import 'vxe-table-plugin-element/dist/style.css'
// VXETable.use(VxeTablePluginElement)

createApp(App).use(VXETable).mount('#app')

表格简单时,可按需引入具体子模块,进一步减小体积。

[⬆ 返回目录](#⬆ 返回目录)

4.2 复杂表格示例

下面是一个带多选、树形、合并单元格的示例,演示 VXE-Table 常用配置和用法:

html 复制代码
<template>
  <div class="product-table">
    <vxe-table
      ref="tableRef"
      :data="tableData"
      :tree-config="{ children: 'children' }"
      :span-method="spanMethod"
      :checkbox-config="{ checkRowKeys: selectedRows }"
      @checkbox-change="onSelectChange"
    >
      <vxe-column type="checkbox" width="60" />
      <vxe-column field="name" title="名称" tree-node />
      <vxe-column field="category" title="分类" />
      <vxe-column field="price" title="价格" />
      <vxe-column field="stock" title="库存" />
    </vxe-table>
  </div>
</template>

<script setup>
import { ref, reactive } from 'vue'

const tableRef = ref(null)
const selectedRows = ref([])

const tableData = reactive([
  {
    id: 1,
    name: '电子产品',
    category: '一级',
    price: '-',
    stock: '-',
    children: [
      { id: 2, name: '手机', category: '二级', price: 3999, stock: 100 },
      { id: 3, name: '电脑', category: '二级', price: 6999, stock: 50 },
    ],
  },
])

// 合并单元格:相同分类合并
const spanMethod = ({ row, columnIndex }) => {
  if (columnIndex === 1) {
    // 可根据业务逻辑返回 [rowspan, colspan]
    return [1, 1]
  }
  return [1, 1]
}

const onSelectChange = () => {
  selectedRows.value = tableRef.value?.getCheckboxRecords() || []
}
</script>

<style scoped lang="scss">
.product-table {
  :deep(.vxe-table) {
    // 使用 :deep() 穿透 scoped 修改 VXE 内部样式
    .vxe-header--column {
      background-color: #f5f7fa;
    }
  }
}
</style>

[⬆ 返回目录](#⬆ 返回目录)

4.3 与 Element Plus 的样式隔离

两个库都带自己的样式,需要控制作用域,避免互相影响:

css 复制代码
// 方案1:用父级包裹,限定 VXE 样式范围
.vxe-container {
  .vxe-table {
    /* 只在这个容器内生效 */
  }
}

// 方案2:提高选择器权重,避免被 Element 覆盖
.product-table.vxe-table-wrapper {
  .vxe-table--render-default {
    border: 1px solid #dcdfe6;
  }
}

[⬆ 返回目录](#⬆ 返回目录)


五、统一封装:减少重复、统一行为

5.1 封装通用表格组件思路

把表格通用逻辑抽成组件,内部根据 type 决定用 el-table 还是 vxe-table,对外统一 API。

html 复制代码
<!-- components/CommonTable/index.vue -->
<template>
  <!-- 简单表格用 el-table -->
  <el-table
    v-if="tableType === 'simple'"
    :data="data"
    v-bind="$attrs"
    v-on="$listeners"
  >
    <el-table-column
      v-for="col in columns"
      :key="col.prop"
      :prop="col.prop"
      :label="col.label"
      :width="col.width"
    />
  </el-table>

  <!-- 复杂表格用 vxe-table -->
  <vxe-table
    v-else
    :data="data"
    v-bind="$attrs"
  >
    <vxe-column
      v-for="col in columns"
      :key="col.prop"
      :field="col.prop"
      :title="col.label"
      :width="col.width"
    />
  </vxe-table>
</template>

<script setup>
defineProps({
  tableType: {
    type: String,
    default: 'simple', // 'simple' | 'complex'
  },
  data: {
    type: Array,
    default: () => [],
  },
  columns: {
    type: Array,
    required: true,
  },
})
</script>

业务侧只需传 tableTypedatacolumns,不用关心内部用的是谁。

[⬆ 返回目录](#⬆ 返回目录)

5.2 表单封装示例

html 复制代码
<!-- components/CommonForm/index.vue -->
<template>
  <el-form
    ref="formRef"
    :model="formData"
    :rules="rules"
    label-width="100px"
    class="common-form"
  >
    <el-form-item
      v-for="item in formConfig"
      :key="item.prop"
      :label="item.label"
      :prop="item.prop"
    >
      <el-input
        v-if="item.type === 'input'"
        v-model="formData[item.prop]"
        :placeholder="item.placeholder"
      />
      <el-select
        v-else-if="item.type === 'select'"
        v-model="formData[item.prop]"
        :options="item.options"
        placeholder="请选择"
      />
    </el-form-item>
  </el-form>
</template>

<script setup>
const props = defineProps({
  formConfig: { type: Array, required: true },
  rules: { type: Object, default: () => ({}) },
})

const formData = reactive({})
const formRef = ref(null)

// 暴露校验、重置等方法
defineExpose({
  validate: () => formRef.value?.validate(),
  resetFields: () => formRef.value?.resetFields(),
})
</script>

[⬆ 返回目录](#⬆ 返回目录)


六、常见踩坑与解决

6.1 样式不生效

现象 :改了 .el-table 样式,页面无变化。
原因 :scoped 限制或选择器优先级不够。
处理 :使用 :deep() 或统一在非 scoped 的覆盖文件中写。

css 复制代码
// 错误:scoped 下可能选不中
.my-page .el-table { }

// 正确:穿透到子组件
.my-page :deep(.el-table) {
  .el-table__header th {
    background: #f5f7fa;
  }
}

[⬆ 返回目录](#⬆ 返回目录)

6.2 VXE-Table 与 Element Plus 样式互相覆盖

现象:两个库的按钮、输入框等样式混在一起。

处理

  1. 统一引入顺序:先 Element,再 VXE
  2. 用父级容器限制 VXE 样式作用范围
  3. 必要时提高选择器权重或使用更具体的类名

[⬆ 返回目录](#⬆ 返回目录)

6.3 按需引入后打包体积仍然偏大

检查:是否全量引入了某个库或样式。

js 复制代码
// 不推荐:全量引入
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
app.use(ElementPlus)

// 推荐:配合 unplugin 按需引入,无需手动 import 组件

[⬆ 返回目录](#⬆ 返回目录)

6.4 表格数据更新但界面不刷新

现象 :用索引改数组 arr[0].name = 'xx',表格不更新。
处理:用响应式 API 或替换整个数组,触发更新。

js 复制代码
// 不推荐
tableData[0].name = '新名字'

// 推荐
tableData[0] = { ...tableData[0], name: '新名字' }
// 或
tableData.splice(0, 1, { ...tableData[0], name: '新名字' })

[⬆ 返回目录](#⬆ 返回目录)


七、工程化落地清单

7.1 项目初始化

  • 统一引入方式(按需 / 全量)
  • 新建 styles/element-override.scss 集中覆盖 Element 样式
  • 新建 styles/vxe-override.scss 集中覆盖 VXE 样式
  • main.js 中按固定顺序引入样式

[⬆ 返回目录](#⬆ 返回目录)

7.2 编码约定

  • 页面/模块使用统一类名前缀(如 order-page
  • 覆盖样式写在 :deep() 或集中覆盖文件中
  • 复杂表格统一用 VXE,简单表格用 el-table
  • 通用表格、表单做成组件,内部统一实现

[⬆ 返回目录](#⬆ 返回目录)

7.3 文档与协作

  • 在项目 README 或内部文档中写明:选型原则、引入方式、覆盖规范
  • Code Review 时检查是否符合规范

[⬆ 返回目录](#⬆ 返回目录)


八、总结

要点 建议
选型 基础表单用 Element Plus,复杂表格用 VXE-Table
引入 Element 使用 unplugin 按需引入,VXE 按需引入所需模块
样式 集中覆盖、使用 :deep()、统一类名前缀
封装 通用表格/表单抽成组件,对外统一 API
避坑 注意引入顺序、响应式更新、选择器优先级

规范的价值在于:一开始多花一点时间定好规矩,后续开发和维护会轻松很多。如果你有自己项目中的具体问题,欢迎在评论区交流。

[⬆ 返回目录](#⬆ 返回目录)


附录:快速参考

Element Plus 常用组件

  • 表单:el-formel-form-itemel-inputel-select
  • 表格:el-tableel-table-column
  • 弹窗:el-dialog
  • 布局:el-rowel-col

VXE-Table 常用能力

  • 树形:tree-config
  • 合并:span-method
  • 多选:checkbox-configtype="checkbox"
  • 虚拟滚动:height + 大数据量

[⬆ 返回目录](#⬆ 返回目录)


🔍 系列模块导航

📝 工程化与协作规范

一、《Vite 工程化实战:alias/env/proxy/ 打包配置全解析,统一项目规范避坑|工程化与协作规范篇》
二、《前端多环境配置规范:dev/test/pre/prod 环境差异与配置,避免生产环境踩坑|工程化与协作规范篇》
三、《前端 Git 协作规范实战:commit message + 分支管理 + 合并流程,告别冲突与混乱|工程化与协作规范篇》
四、《ESLint + Prettier 实战:统一前端代码风格,自动修复语法格式问题|工程化与协作规范篇》

五、《Element Plus/VXE-Table UI 组件库规范:统一用法实战,避开样式冲突与维护混乱|工程化与协作规范篇》

👉 跟着系列慢慢学,把技术功底扎扎实实地打牢~

📚 系列总览

前端体系化学习完全体:基础 → 规范 → 架构 → 大厂面试

四套系列、百余篇高质量实战文,从入门到进阶,一站式补齐前端核心能力

每个系列完结后,都会整理成一篇完整导航文并附上直达链接,方便大家按顺序、体系化学习。

全套内容持续更新中,敬请期待~


技术成长,从来不是比谁写得快,而是比谁写得稳、规范、可维护

哪怕每次只吃透一条规范,长期下来,差距会非常明显。

后续我会持续更新前端规范、工程化、可维护代码相关实战干货,帮你告别面条代码、维护噩梦,在开发与面试中更有底气。

觉得有用欢迎 点赞 + 收藏 + 关注,不错过每一篇实战内容。

我是 Eugene,与你一起写规范、写优质代码,我们下篇干货见~

相关推荐
前端Hardy2 小时前
前端工程师必备的 10 个 AI 万能提示词(Prompt),复制直接用,效率再翻倍!
前端·javascript·面试
BioRunYiXue2 小时前
Nature Methods:CellVoyager 自主 AI 智能体开启生物数据分析新时代
大数据·开发语言·前端·javascript·人工智能·数据挖掘·数据分析
再玉米地里吃过亏3 小时前
ONENET平台API鉴权错误
前端
网络点点滴3 小时前
Vue3中Suspense的使用
前端·javascript·vue.js
饼干哥哥3 小时前
搭建一个云端Skills系统,随时随地记录TikTok爆款
前端·后端
酉鬼女又兒4 小时前
零基础快速入门前端Web存储(sessionStorage & localStorage)知识点详解与蓝桥杯考点应用(可用于备赛蓝桥杯Web应用开发)
开发语言·前端·javascript·职场和发展·蓝桥杯·html
FollowHeart4 小时前
自建私有日记本:MyDiary —— 属于你的 NAS 极简写作空间
vue.js·github
DanCheOo4 小时前
# 从"会用 AI"到"架构 AI":高级前端的认知升级
前端·ai编程
社恐的下水道蟑螂4 小时前
前端面试必问 Git 通关指南:常用命令速查 + merge/rebase 深度辨析,看完再也不慌
前端·git·面试