Vue.js: UI 组件库集成

最后更新:2026-08-26

UI 组件库能让你避免重复造轮子——Button / Table / Form / Modal 等常见组件,几行代码就能用。Vue 3 生态有 5+ 主流 UI 库(Element Plus / Naive UI / Vuetify / PrimeVue / Ant Design Vue),选对能省 50% 开发时间。

选 UI 库要考虑 5 大维度:组件丰富度 / TypeScript 支持 / 主题定制 / 包大小 / 社区活跃度。本课帮你做出正确选择。

1. 你将学到


2. 一个"5 个表格"组件重复 5 次的噩梦

(1) 痛点:每个表格都从零写

Alice 的后台有 5 个不同的表格视图,每个都是从零写起:

VUE
<!-- ❌ 翻车版:5 个表格,5 份不同代码 -->
<!-- OrdersTable.vue -->
<template>
  <table>
    <thead><tr><th>ID</th><th>User</th><th>Total</th></tr></thead>
    <tbody>
      <tr v-for="order in orders" :key="order.id">
        <td>{{ order.id }}</td>
        <td>{{ order.user }}</td>
        <td>${{ order.total }}</td>
      </tr>
    </tbody>
  </table>
</template>

<!-- ProductsTable.vue - 类似 -->
<!-- UsersTable.vue - 类似 -->
<!-- ... 还有 3 个 ... -->

5 个表格 × 200 行 = 1000 行重复代码。每改 1 个样式要改 5 处。

(2) UI 组件库解法:1 个 el-table,5 处复用

VUE
<!-- ✅ 正确版:用 Element Plus 的 el-table -->
<template>
  <el-table :data="orders" stripe>
    <el-table-column prop="id" label="ID" width="80" />
    <el-table-column prop="user" label="User" />
    <el-table-column prop="total" label="Total" :formatter="formatTotal" />
  </el-table>
</template>

<script setup>
import { ElTable, ElTableColumn } from 'element-plus'

const orders = ref([...])
function formatTotal(row) { return `$${row.total}` }
</script>

1 个 el-table,5 处复用。所有表格样式统一、交互一致。

(3) 收益

使用 Element Plus 后:


3. 5 大 Vue 3 UI 库对比

(1) 5 大库速查

风格 组件数 包大小 TypeScript 适用
Element Plus 桌面端 80+ ~250KB 国内最流行、中后台
Naive UI 桌面端 80+ ~150KB 现代风格、Vue 3 优先
Vuetify Material 80+ ~300KB Material Design 应用
PrimeVue 多风格 90+ ~200KB 主题多、组件全
Ant Design Vue Ant Design 70+ ~180KB 蚂蚁风格、企业级

(2) 5 大维度详细对比

维度 Element Plus Naive UI Vuetify PrimeVue Ant Design Vue
GitHub ⭐ 24k+ 16k+ 40k+ 11k+ 20k+
Vue 3 一等公民
TypeScript ⭐⭐⭐⭐ ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐ ⭐⭐⭐⭐ ⭐⭐⭐⭐
主题定制 CSS 变量 CSS 变量 SCSS SCSS + 主题 less + 主题
包大小
中文文档 ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐ ⭐⭐⭐ ⭐⭐⭐ ⭐⭐⭐⭐
社区活跃 ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐ ⭐⭐⭐ ⭐⭐⭐ ⭐⭐⭐⭐
学习曲线 平缓 平缓

(3) 5 大选择建议

场景 推荐
国内中后台(电商/CRM/ERP) Element Plus ⭐⭐⭐⭐⭐
现代风格 SaaS Naive UI ⭐⭐⭐⭐
Material Design 应用 Vuetify ⭐⭐⭐⭐
多主题(暗色/亮色/高对比度) PrimeVue ⭐⭐⭐⭐
Ant Design 生态 Ant Design Vue ⭐⭐⭐⭐

4. Element Plus 实战

(1) 安装

BASH
npm install element-plus @element-plus/icons-vue

(2) 全局注册(简单)

JS
// main.js
const { createApp } = Vue
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
import App from './App.vue'

const app = createApp(App)
app.use(ElementPlus)

// 注册所有图标
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
  app.component(key, component)
}

app.mount('#app')

(3) 按需引入(推荐,节省 50% 体积)

BASH
npm install -D unplugin-vue-components unplugin-auto-import
TS
// vite.config.ts
import AutoImport from 'unplugin-auto-import'
import Components from 'unplugin-vue-components'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'

export default defineConfig({
  plugins: [
    AutoImport({
      resolvers: [ElementPlusResolver()],
      dts: 'src/auto-imports.d.ts'
    }),
    Components({
      resolvers: [ElementPlusResolver()],
      dts: 'src/components.d.ts'
    })
  ]
})
VUE
<!-- ✅ 无需 import,自动按需引入 -->
<template>
  <el-button>Click</el-button>
  <el-input v-model="search" />
  <el-table :data="list">
    <el-table-column prop="name" label="Name" />
  </el-table>
</template>

(4) 5 大核心组件

VUE
<template>
  <!-- 1. Button -->
  <el-button type="primary" @click="onClick">Primary</el-button>
  
  <!-- 2. Form -->
  <el-form :model="form" :rules="rules" ref="formRef">
    <el-form-item label="Name" prop="name">
      <el-input v-model="form.name" />
    </el-form-item>
  </el-form>
  
  <!-- 3. Table -->
  <el-table :data="list" stripe>
    <el-table-column prop="name" label="Name" />
  </el-table>
  
  <!-- 4. Dialog -->
  <el-dialog v-model="visible" title="Edit">
    <p>Content</p>
  </el-dialog>
  
  <!-- 5. Message -->
  <el-button @click="$message.success('Saved!')">Click</el-button>
</template>

5. 主题定制

(1) CSS 变量覆盖(推荐)

SCSS
// src/styles/element-plus.scss
:root {
  --el-color-primary: #42b883;       // 主色改为 Vue 绿
  --el-color-success: #67c23a;
  --el-color-warning: #e6a23c;
  --el-color-danger: #f56c6c;
  --el-color-info: #909399;
  
  --el-border-radius-base: 8px;      // 圆角加大
  --el-font-size-base: 14px;
}
JS
// main.js
import './styles/element-plus.scss'
import 'element-plus/dist/index.css'

(2) SCSS 变量(深度定制)

SCSS
// src/styles/element-plus-vars.scss
@forward 'element-plus/theme-chalk/src/common/var.scss' with (
  $colors: (
    'primary': ('base': #42b883),
    'success': ('base': #67c23a),
    'warning': ('base': #e6a23c),
    'danger':  ('base': #f56c6c),
    'info':    ('base': #909399)
  )
);
JS
// main.js
import './styles/element-plus-vars.scss'
import 'element-plus/dist/index.css'

(3) 暗色模式

SCSS
// 暗色主题
:root {
  --el-color-primary: #42b883;
  --el-bg-color: #1a1a1a;
  --el-text-color-primary: #ffffff;
}

html.dark {
  --el-bg-color: #1a1a1a;
  --el-text-color-primary: #ffffff;
}

6. 组件二次封装

(1) 业务组件示例

VUE
<!-- components/BusinessTable.vue -->
<template>
  <el-table 
    :data="data" 
    v-loading="loading"
    stripe
    border
    :max-height="maxHeight"
  >
    <el-table-column type="index" label="#" width="60" />
    <el-table-column 
      v-for="col in columns" 
      :key="col.key"
      :prop="col.key" 
      :label="col.label"
      :width="col.width"
      :formatter="col.formatter"
    />
  </el-table>
  
  <el-pagination
    v-model:current-page="page"
    v-model:page-size="size"
    :total="total"
    :page-sizes="[10, 20, 50, 100]"
    layout="total, sizes, prev, pager, next"
    @current-change="onPage"
    @size-change="onSize"
  />
</template>

<script setup lang="ts">
// 业务封装:自动 loading + 分页 + 列定义
const props = defineProps<{
  data: any[]
  columns: Array<{ key: string; label: string; width?: number; formatter?: Function }>
  total: number
  loading?: boolean
  maxHeight?: number
}>()

const emit = defineEmits<{
  'update:page': [page: number]
  'update:size': [size: number]
}>()

const page = ref(1)
const size = ref(20)

function onPage(p) { emit('update:page', p) }
function onSize(s) { emit('update:size', s) }
</script>
VUE
<!-- 使用:3 行搞定 1 个表格 -->
<BusinessTable :data="orders" :columns="orderColumns" :total="100" />

(2) 5 大封装好处


7. Icon 库集成

(1) 安装

BASH
npm install -D unplugin-icons @iconify-json/carbon

(2) 配置

TS
// vite.config.ts
import Icons from 'unplugin-icons/vite'
import { FileSystemIconLoader } from 'unplugin-icons/dist/loader'

export default defineConfig({
  plugins: [
    Icons({
      compiler: 'vue3',
      autoInstall: true,  // 自动安装图标集
      collections: {
        carbon: () => import('@iconify-json/carbon/icons.json').then(i => i.default)
      }
    })
  ]
})

(3) 使用

VUE
<template>
  <!-- Carbon 图标(10万+ 个) -->
  <IconCarbonUser size="20" />
  <IconCarbonShoppingCart size="24" color="green" />
  <IconCarbonTrashCan size="20" @click="delete" />
</template>

(4) 5 大 Icon 库对比

图标数 加载方式 包大小
Iconify 200,000+ 按需(推荐) 0
Element Icons 300+ 全部 / 按需 100KB
Material Icons 2,000+ 全部 / 按需 300KB
Font Awesome 7,000+ 全部 1MB+
Heroicons 300+ 按需 50KB

8. 完整示例:5 大 UI 库场景

▶ 示例:5 大 UI 库对比(⚠️ 需 Vite + npm install)

包大小 风格
Element Plus 24k 桌面端
Naive UI 16k 现代
Vuetify 40k Material
PrimeVue 11k 多风格
Ant Design Vue 20k Ant Design

▶ 示例:5 大核心组件(以 Element Plus 为例)

VUE
<!-- 需 Vite + npm install element-plus -->
<el-button>Button</el-button>
<el-form>Form</el-form>
<el-table>Table</el-table>
<el-dialog>Dialog</el-dialog>
<el-message>Message</el-message>
▶ 试一试

▶ 示例:5 大主题定制

SCSS
/* 1. CSS 变量(推荐) */
:root { --el-color-primary: #42b883; }

/* 2. SCSS 变量(深度定制) */
@forward 'var.scss' with ($colors: ...);

/* 3. 暗色模式 */
:root.dark { --el-bg-color: #1a1a1a; }

/* 4. 自定义主题 */
@import 'element-plus/theme-chalk/dark/css-vars.css';

/* 5. 运行时切换 */
document.documentElement.classList.toggle('dark')
▶ 试一试

▶ 示例:5 大 Icon 库

图标数
Iconify 200,000+
Element Icons 300+
Material 2,000+
Font Awesome 7,000+
Heroicons 300+

▶ 示例:5 个常见错误速查

错误 现象 解决
全量引入包大 bundle 500KB 用 unplugin-vue-components 按需
主题色改不动 用了 SCSS 改用 CSS 变量
图标不显示 字体加载失败 用 unplugin-icons SVG
TS 类型错误 import 缺类型 装 @types 包
国际化失效 locale 错 配 i18n

❓ 常见问题

Q 5 大 UI 库选哪个?
A 国内中后台 → Element Plus(最流行)。现代 SaaS → Naive UI(小而美)。Material 应用 → Vuetify。Ant Design 生态 → Ant Design Vue。
Q 全量引入 vs 按需引入?
A 全量简单但 bundle 大(500KB)。按需推荐(unplugin-vue-components),节省 50% 体积。
Q 怎么改 Element Plus 主题色?
A 覆盖 CSS 变量 --el-color-primary。SCSS 变量定制需用 unplugin-element-plus 主题编译。
Q Element Plus + TypeScript 完整支持吗?
A 是。Element Plus 2.x 完全 TypeScript 重写,类型推断完整。
Q UI 库能混用吗(如 Element Plus + Naive UI)?
A 技术上可以,但样式冲突难调。不推荐混用,选 1 个主库 + 1 个轻量库(如 Element Plus + Headless UI)。
Q unplugin-vue-components vs 全局注册?
A unplugin 自动按需引入,bundle 小 50%。全局简单但 bundle 大。推荐按需。
Q Icon 库怎么选?
A Iconify(200,000+ 跨多套)+ unplugin-icons 按需。零运行时开销。

📖 小节


📝 作业

  1. 基础题(难度⭐) 集成 Element Plus 到 Vue 3 项目:

    • 安装 + 按需引入
    • 5 个核心组件(Button / Form / Table / Dialog / Message)
    • 主题色改为项目主色
  2. 进阶题(难度⭐⭐) 实现完整的 Element Plus 集成:

    • 5 大组件全用(Button / Form / Table / Dialog / Message)
    • 暗色模式切换
    • Iconify 图标(10 个不同图标)
    • 二次封装 BusinessTable 组件
  3. 挑战题(难度⭐⭐⭐) 实现完整的"企业级 UI 库集成":

    1. Element Plus + Naive UI 混用(主 + 辅)
    2. 5 大主题色(主色 / 辅色 / 成功 / 警告 / 危险)
    3. 暗色模式 + 自动跟随系统
    4. 10+ 二次封装业务组件
    5. Iconify 200,000+ 图标
    6. TypeScript 强类型
    7. 性能优化(按需 + 树摇 + CDN)
Web-Tutorial.com

Web-Tutorial 技术团队

由多位开发者共同维护的编程教程平台。每篇教程由对应领域的开发者编写和审核,确保内容准确可靠。如发现任何问题,欢迎向我们反馈。

100%

🙏 帮我们做得更好

我们是刚上线的编程教程站,几个人的小团队,精力有限。页面虽经检查,难免还有疏漏——链接失效、排版错乱、内容有误、语言生硬……

如果您发现了,麻烦告诉我们,我们会在收到反馈后第一时间进行修复,再次感谢您的光临 🙏