Vue 3 UI コンポーネントライブラリの統合:Element Plus / Naive UI / Vuetify――選定と実装
UIコンポーネントライブラリを使えば、車輪の再発明を避けることができます。Button、Table、Form、Modalといった一般的なコンポーネントを、わずか数行のコードで利用できます。Vue 3のエコシステムには、5つ以上の主要なUIライブラリ(Element Plus、Naive UI、Vuetify、PrimeVue、Ant Design Vue)が存在し、適切なものを選択することで、開発時間を50%短縮できます。
UIライブラリを選ぶ際には、コンポーネントの豊富さ/TypeScriptのサポート/テーマのカスタマイズ/パッケージサイズ/コミュニティの活発さという5つの重要な要素を考慮する必要があります。このレッスンでは、適切な選択ができるようお手伝いします。
1. 学習内容
- Vue 3用UIライブラリ5選の比較(Element Plus / Naive UI / Vuetify / PrimeVue / Ant Design Vue)
- オンデマンドインポート (unplugin-vue-components)
- テーマのカスタマイズ(CSS変数/SCSS変数)
- 部品の二次包装(業務ニーズに合わせてカスタマイズ)
- アイコンライブラリの統合(@iconify / unplugin-icons)
- よくある5つの間違い
2. 「5テーブル」コンポーネントの悪夢が5回繰り返される
(1) 課題:すべてのテーブルを一から作成しなければならないこと
アリスの管理画面には、それぞれ一から作成された5種類のテーブルビューがありました:
VUE
<!-- ❌ The "Flip" Version:5 A table,5 Different code snippets -->
<!-- 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 - Similar -->
<!-- UsersTable.vue - Similar -->
<!-- ... And also 3 more ... -->
5つのテーブル × 200行 = 1,000行の重複コード。1つのスタイルを変更するたびに、5か所の変更を行わなければなりません。
(2) UIコンポーネントライブラリのソリューション:el-tableが1つあり、5か所で再利用されている
VUE
<!-- ✅ Correct Version: Use 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テーブルが5か所で再利用されています。すべてのテーブルは統一されたスタイルと一貫した操作性を備えています。
(3) 収益
Element Plus を使用した後:
- コード行数:1,000行 → 200行(-80%)
- スタイルの一貫性:100%一貫している
- 新しいテーブル:1行のテンプレート
- TypeScript: 完全な型推論
- アクセシビリティ:アクセシビリティ機能が組み込まれています
3. Vue 3の主要なUIライブラリトップ5の比較
(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 | ✅ | Ant Designスタイル、エンタープライズグレード |
(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つの重要な選び方のポイント
| シナリオ | 推奨事項 |
|---|---|
| 国内向けバックオフィスシステム(Eコマース/CRM/ERP) | Element Plus ⭐⭐⭐⭐⭐ |
| モダンなスタイルのSaaS | 素朴なUI ⭐⭐⭐⭐ |
| マテリアルデザインアプリ | Vuetify ⭐⭐⭐⭐ |
| 複数のテーマ(ダーク/ライト/高コントラスト) | PrimeVue ⭐⭐⭐⭐ |
| Ant Design エコシステム | Ant Design Vue ⭐⭐⭐⭐ |
4. Element Plusの実践
(1) インストール
BASH
npm install element-plus @element-plus/icons-vue
(2) グローバル登録(簡易版)
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.use(ElementPlus)
// Register All Icons
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
<!-- ✅ Not required import,Automatic On-Demand 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; // 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-base: 8px; // Increase Corner Radius
--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
// 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. 部品の二次包装
(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">
// 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>
VUE
<!-- Usage:3 All set 1 A table -->
<BusinessTable :data="orders" :columns="orderColumns" :total="100" />
(2) カプセル化の5つの主な利点
- コードの重複を削減:50以上の共有テーブル
- 統一されたスタイル:すべての表のスタイルが同じです
- ビジネス向けカスタマイズ:自動読み込み + ページネーション + 空の状態
- TypeScript: 強型付けのプロップス
- 保守性が高い:1か所を変更するだけで、Nか所に反映される
7. アイコンライブラリの統合
(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, // Automatically Install Icon Sets
collections: {
carbon: () => import('@iconify-json/carbon/icons.json').then(i => i.default)
}
})
]
})
(3) 使い方
VUE
<template>
<!-- Carbon Icon (100,000+) -->
<IconCarbonUser size="20" />
<IconCarbonShoppingCart size="24" color="green" />
<IconCarbonTrashCan size="20" @click="delete" />
</template>
(4) 主要なアイコンライブラリ5選の比較
| ライブラリ | アイコン数 | 読み込み方法 | パッケージサイズ |
|---|---|---|---|
| Iconify | 200,000以上 | オンデマンド(推奨) | 0 |
| 要素アイコン | 300以上 | すべて / オンデマンド | 100KB |
| Material Icons | 2,000以上 | すべて / オンデマンド | 300KB |
| Font Awesome | 7,000以上 | すべて | 1MB以上 |
| Heroicons | 300以上 | オンデマンド | 50KB |
8. 完全な例:主要なUIライブラリを用いた5つのシナリオ
(1) ▶ サンプル:. 主要なUIライブラリトップ5の比較
| ライブラリ | ⭐ | パッケージサイズ | スタイル |
|---|---|---|---|
| Element Plus | 24k | ミディアム | デスクトップ |
| シンプルなUI | 16k | コンパクト | モダン |
| Vuetify | 40k | Large | Material |
| PrimeVue | 11k | ミディアム | 複数のスタイル |
| Ant Design Vue | 20k | Medium | Ant Design |
(2) ▶ サンプル:. 5つの主要な構成要素
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>
(3) ▶ サンプル:. 5つの主要テーマのカスタマイズ
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')
(4) ▶ サンプル:. 主要なアイコンライブラリ5選
| ライブラリ | アイコンの数 |
|---|---|
| Iconify | 200,000以上 |
| 要素アイコン | 300以上 |
| 素材 | 2,000以上 |
| Font Awesome | 7,000以上 |
| ヒーローアイコン | 300以上 |
(5) ▶ サンプル:. よくある5つの間違いに関するクイックリファレンス
| エラー | 症状 | 解決策 |
|---|---|---|
| Baoda パッケージ全体をインポート | バンドルサイズ 500KB | 必要に応じて unplugin-vue-components を使用 |
| テーマの色を変更できない | SCSSの使用 | CSS変数に切り替える |
| アイコンが表示されない | フォントの読み込みに失敗しました | unplugin-icons SVG を使用する |
| TS 型エラー | インポートで型が指定されていません | @types パッケージをインストールしてください |
| 国際化の失敗 | ロケールの不一致 | i18nの設定 |
❓ よくある質問
Q トップ5のUIライブラリのうち、どれを選ぶべきですか?
A 国内向けのバックエンドや管理画面には → Element Plus(最も人気があります)。モダンなSaaSには → Naive UI(コンパクトで洗練されています)。Materialスタイルのアプリには → Vuetify。Ant Designエコシステムには → Ant Design Vue。
Q フルインポートとオンデマンドインポート、どちらが良いですか?
A フルインポートは簡単ですが、バンドルサイズが大きくなります(500KB)。サイズを50%削減できるオンデマンドインポート(unplugin-vue-components)をお勧めします。
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 とグローバル登録の違いは?
A unplugin は必要に応じてコンポーネントを自動的にインポートするため、バンドルサイズが 50% 小さくなります。グローバル登録は簡単ですが、バンドルサイズが大きくなってしまいます。オンデマンドでの読み込みをお勧めします。
Q アイコンライブラリはどのように選べばいいですか?
A Iconify(複数のセットにまたがる20万個以上のアイコン)+必要に応じてunplugin-iconsを使用します。実行時のオーバーヘッドはゼロです。
📖 まとめ
- 5つのVue 3 UIライブラリ:Element Plus / Naive UI / Vuetify / PrimeVue / Ant Design Vue
- Element Plusは中国で最も人気があり、豊富なコンポーネント(80以上)とTypeScriptのサポートを備えています
- オンデマンドインポート:unplugin-vue-components + ElementPlusResolver
- テーマのカスタマイズ:CSS変数の上書き(推奨)+ SCSS変数(詳細)
- 二次カプセル化:ビジネスコンポーネントにおけるコードの重複を軽減する
- 20万点以上のアイコンをアイコン化 + unplugin-icons オンデマンド
- 5つのアイコンライブラリ:Iconify / Element / Material / Font Awesome / Heroicons
📝 練習問題
(1) 基礎問題(難易度:⭐)
Element Plus を Vue 3 プロジェクトに組み込む方法:
- オンデマンドでのインストールとインポート
- 5つの主要コンポーネント(ボタン/フォーム/テーブル/ダイアログ/メッセージ)
- テーマの色をプロジェクトのメインカラーに変更する
(2) 上級問題(難易度:⭐⭐)
Element Plusとの完全な統合を実施する:
- 5つのコンポーネントの統合(ボタン/フォーム/テーブル/ダイアログ/メッセージ)
- ダークモードの切り替え
- アイコンのアイコン化(10種類のアイコン)
- BusinessTable コンポーネントを再ラップする
(3) チャレンジ問題(難易度:⭐⭐⭐)
完全な「エンタープライズレベルのUIライブラリ統合」を実現する:
- Element Plus と Naive UI の組み合わせ(プライマリ + セカンダリ)
- 5つの主要な色(基本色/補助色/成功/注意/危険)
- ダークモード + 自動フォロー機能
- 二次包装用のビジネスコンポーネント10以上
- 20万個以上のアイコンをアイコン化
- TypeScriptの厳格な型付け
- パフォーマンスの最適化(オンデマンド + ツリーシェーキング + CDN)



