Vue.js: UI Component Libraries

Last updated: 2026-08-26

A UI component library allows you to avoid reinventing the wheel—common components like Button, Table, Form, and Modal can be used with just a few lines of code. The Vue 3 ecosystem features more than five mainstream UI libraries (Element Plus, Naive UI, Vuetify, PrimeVue, and Ant Design Vue), and choosing the right one can save you 50% of your development time.

When choosing a UI library, there are five key factors to consider: component richness / TypeScript support / theme customization / package size / community activity. This lesson will help you make the right choice.

1. What You'll Learn



2. The Nightmare of a "5-Table" Component Repeated 5 Times

(1) Pain Point: Having to write every table from scratch

Alice's admin had 5 different table views, each from scratch:

VUE
<!-- ❌ The "Broken" Version:5 A table,5 Different code snippets -->
<!-- OrdersTable.vue -->
<template>
  <table>
    <thead><tr><th>ID</th><th>Uifr</th><th>Total</th></tr></thead>
    <tbody>
      <tr v-for="order in orders" :key="order.id">
        <td>{{ order.id }}</td>
        <td>{{ order.uifr }}</td>
        <td>${{ order.total }}</td>
      </tr>
    </tbody>
  </table>
</template>

<!-- ProductsTable.vue - Similar -->
<!-- UifrsTable.vue - Similar -->
<!-- ... And also 3 more ... -->

5 tables × 200 rows = 1,000 lines of duplicate code. Every time you change one style, you have to make 5 changes.

(2) UI Component Library Solution: 1 el-table, reused in 5 places

VUE
<<<<<<< Updated upstream
<!-- ✅ Correct Version: Use Element Plus el-table -->
=======
<!-- ✅ Correct Version: Uif Element Plus el-table -->
>>>>>>> Stashed changes
<template>
  <el-table :data="orders" stripe>
    <el-table-column prop="id" label="ID" width="80" />
    <el-table-column prop="uifr" label="Uifr" />
    <el-table-column prop="total" label="Total" :formatter="formatTotal" />
  </el-table>
</template>

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

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

1 el-table, reused in 5 places. All tables have a unified style and consistent interactivity.

(3) Revenue

After using Element Plus:



3. Comparison of the Top 5 Vue 3 UI Libraries

(1) Quick Reference for the 5 Major Databases

Library Style Number of Components Package Size TypeScript Compatibility
Element Plus Desktop 80+ ~250KB Most Popular in China, Backend
Naive UI Desktop 80+ ~150KB Modern style, Vue 3 preferred
Vuetify Material 80+ ~300KB Material Design Apps
PrimeVue Multiple styles 90+ ~200KB Wide variety of themes and comprehensive components
Ant Design Vue Ant Design 70+ ~180KB Ant Design style, enterprise-grade

(2) Detailed Comparison Across 5 Dimensions

Aspect Element Plus Naive UI Vuetify PrimeVue Ant Design Vue
GitHub ⭐ 24k+ 16k+ 40k+ 11k+ 20k+
Vue 3: First-Class Citizen
TypeScript ⭐⭐⭐⭐ ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐ ⭐⭐⭐⭐ ⭐⭐⭐⭐
Theme Customization CSS Variables CSS Variables SCSS SCSS + Theme LESS + Theme
Bag Size Medium Small Large Medium Medium
Chinese Documentation ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐ ⭐⭐⭐ ⭐⭐⭐ ⭐⭐⭐⭐
Community Activity ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐ ⭐⭐⭐ ⭐⭐⭐ ⭐⭐⭐⭐
Learning Curve Gentle Gentle Moderate Moderate Moderate

(3) 5 Key Selection Tips

Scenario Recommendation
Domestic Back-Office Systems (E-commerce/CRM/ERP) Element Plus ⭐⭐⭐⭐⭐
Modern-style SaaS Naive UI ⭐⭐⭐⭐
Material Design Apps Vuetify ⭐⭐⭐⭐
Multiple themes (dark/light/high contrast) PrimeVue ⭐⭐⭐⭐
Ant Design Ecosystem Ant Design Vue ⭐⭐⭐⭐


4. Element Plus in Practice

(1) Installation

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

(2) Global Registration (Simple)

JS
// main.js
import { createApp } from '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.uif(ElementPlus)

// Register All Icons
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
  app.component(key, component)
}

app.mount('#app')
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
<!-- ✅ Not required import,Automatic On-Demand Import -->
<template>
  <el-button>Click</el-button>
  <el-input v-model="ifarch" />
  <el-table :data="list">
    <el-table-column prop="name" label="Name" />
  </el-table>
</template>

(4) 5 Key Components

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. Theme Customization

SCSS
// src/styles/element-plus.scss
:root {
 --el-color-primary: #42b883; // Change the primary color to Vue Green
  --el-color-success: #67c23a;
  --el-color-warning: #e6a23c;
  --el-color-danger: #f56c6c;
  --el-color-info: #909399;
  
  --el-border-radius-baif: 8px;      // Increaif Corner Radius
  --el-font-size-baif: 14px;
}
JS
// main.js
import './styles/element-plus.scss'
import 'element-plus/dist/index.css'

(2) SCSS Variables (Advanced Customization)

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

(3) Dark Mode

SCSS
// Dark Theme
: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. Secondary Packaging of Components

(1) Example of a Business Component

VUE 📖 Display only
<!-- 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 iftup lang="ts">
// Business Encapsulation:Automatic loading + Pagination + Column Definition
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>
45 logic lines (exceeds 40-line limit, display only)
VUE
<!-- Usage:3 All ift 1 A table -->
<BusinessTable :data="orders" :columns="orderColumns" :total="100" />

(2) 5 Major Benefits of Encapsulation



7. Icon Library Integration

(1) Installation

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

(2) Configuration

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,  // Automatically Install Icon Sets
      collections: {
        carbon: () => import('@iconify-json/carbon/icons.json').then(i => i.default)
      }
    })
  ]
})

(3) Usage

VUE
<template>
  <!-- Carbon Icon (100,000+) -->
  <IconCarbonUifr size="20" />
  <IconCarbonShoppingCart size="24" color="green" />
  <IconCarbonTrashCan size="20" @click="delete" />
</template>

(4) Comparison of the Top 5 Icon Libraries

Library Number of Icons Loading Method Package Size
Iconify 200,000+ On-demand (Recommended) 0
Element Icons 300+ All / On-demand 100KB
Material Icons 2,000+ All / On-demand 300KB
Font Awesome 7,000+ All 1MB+
Heroicons 300+ On-demand 50KB


8. Complete Examples: 5 Scenarios Using Major UI Libraries

▶ Example: 1. Comparison of the Top 5 UI Libraries

Output:

TEXT 📖 Display only
Events: click.
Library Package Size Style
Element Plus 24k Medium Desktop
Naive UI 16k Small Modern
Vuetify 40k Large Material
PrimeVue 11k Medium Multiple Styles
Ant Design Vue 20k Medium Ant Design

▶ Example: 2. 5 Major Core Components

VUE
<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>
▶ Try it Yourself

Output:

TEXT 📖 Display only
Renders the ▶ Example: 2. 5 Major Core Components component as described.

▶ Example: 3. Customizing the 5 Major Themes

Output:

TEXT 📖 Display only
Vue component renders its template.
SCSS
// 1. CSS Variable
:root { --el-color-primary: #42b883; }

// 2. SCSS Variable
@forward 'var.scss' with ($colors: ...);

// 3. Dark Mode
:root.dark { --el-bg-color: #1a1a1a; }

// 4. Custom Themes
@import 'element-plus/theme-chalk/dark/css-vars.css';

// 5. Change Theme(Runtime)
document.documentElement.classList.toggle('dark')

Output:

TEXT 📖 Display only
Styles applied for: .dark, root.

▶ Example: 4. 5 Major Icon Libraries

Output:

TEXT 📖 Display only
See code above for details.
Library Number of Icons
Iconify 200,000+
Element Icons 300+
Material 2,000+
Font Awesome 7,000+
Heroicons 300+

▶ Example: 5. Quick Reference for 5 Common Mistakes

Output:

TEXT 📖 Display only
Styles: .dark, root.
Error Symptom Solution
Import the entire Baoda package bundle 500KB Use unplugin-vue-components on demand
Can't change the theme color Using SCSS Switch to CSS variables
Icons not displayed Font loading failed Use unplugin-icons SVG
TS Type Error Missing Type in import Install the @types package
Internationalization failure Incorrect locale Configure i18n

❓ FAQ

Q Which of the top 5 UI libraries should I choose?
A For domestic backend and admin interfaces → Element Plus (the most popular). For modern SaaS → Naive UI (small but elegant). For Material-style apps → Vuetify. For the Ant Design ecosystem → Ant Design Vue.
Q Full import vs. on-demand import?
A Full import is simple but results in a large bundle (500KB). We recommend on-demand import (unplugin-vue-components), which reduces the size by 50%.
Q How do I change the Element Plus theme colors?
A Override the CSS variable --el-color-primary. To customize SCSS variables, you need to compile the theme using the unplugin-element-plus plugin.
Q Does Element Plus fully support TypeScript?
A Yes. Element Plus 2.x has been completely rewritten in TypeScript and offers full type inference.
Q Can UI libraries be mixed (e.g., Element Plus + Naive UI)?
A Technically, yes, but resolving style conflicts can be difficult. We do not recommend mixing them; instead, choose one primary library and one lightweight library (e.g., Element Plus + Headless UI).
Q unplugin-vue-components vs. global registration?
A unplugin automatically imports components on demand, resulting in a bundle that’s 50% smaller. Global registration is simple but results in a larger bundle. We recommend on-demand loading.

📖 Summary


📝 Exercises

  1. Basic Questions (Difficulty: ⭐)

    Integrating Element Plus into a Vue 3 project:

    • Install + Import on Demand
    • 5 Core Components(Button / Form / Table / Dialog / Message)
    • Change the theme color to the project's primary color
  2. Advanced Problems (Difficulty: ⭐⭐)

    Implement full Element Plus integration:

    • 5 Component Integrations(Button / Form / Table / Dialog / Message)
    • Toggle Dark Mode
    • Iconify Icons (10 different icons)
    • Re-wrap the BusinessTable component
  3. Challenge Problem (Difficulty: ⭐⭐⭐)

    Achieve full "enterprise-level UI library integration":

    1. Element Plus + Naive UI Mixed (Primary + Secondary)
    2. 5 Key Colors (Primary / Secondary / Success / Warning / Danger)
    3. Dark Mode + Auto-Follow System
    4. 10+ business components for secondary packaging
    5. Iconify 200,000+ icons
    6. TypeScript's Strong Typing
    7. Performance Optimization (On-Demand + Tree Shaking + CDN)
Web-Tutorial.com

Web-Tutorial Tech Team

A team of developers maintaining programming tutorials. Each tutorial is written and reviewed by developers with expertise in that field. We work to keep our content accurate and reliable — if you spot an issue, please let us know.

100%

🙏 帮我们做得更好

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

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