rayyy-vue-table-components
Version:
Vue 3 + Element Plus 表格組件庫
1,983 lines (1,561 loc) • 49.2 kB
Markdown
# Vue Table Components
<p align="center">
<img src="https://img.shields.io/npm/v/rayyy-vue-table-components.svg" alt="npm version">
<img src="https://img.shields.io/npm/dm/rayyy-vue-table-components.svg" alt="npm downloads">
<img src="https://img.shields.io/github/license/rayshao/vue-table-components.svg" alt="license">
<img src="https://img.shields.io/badge/vue-3.x-brightgreen.svg" alt="vue">
</p>
基於 Vue 3 + Element Plus + TypeScript 的現代化組件庫,提供豐富的表格、表單、佈局和交互組件,支援完整的 TypeScript 類型定義和現代化開發體驗。
## ✨ 特性
- 🚀 **現代化技術棧** - 基於 Vue 3 + TypeScript + Element Plus + Tailwind CSS
- 📦 **開箱即用** - 提供完整的組件解決方案,包含表格、表單、佈局、交互組件
- 🎯 **類型安全** - 完整的 TypeScript 類型定義,支援智能提示和類型檢查
- 🌐 **國際化支持** - 支援多語言切換,與外部專案 i18n 完美整合
- 📱 **響應式設計** - 使用 Tailwind CSS,適配各種設備尺寸
- 🔧 **高度可配置** - 靈活的配置選項和豐富的插槽支持
- 🎨 **樣式系統** - 多種樣式導入方式,支援自定義主題和 Tailwind CSS 集成
- 🛠️ **現代化工具** - Sass 模組化 + TypeScript 樣式工具 + 自動導入
- 💡 **豐富組件** - 15 個組件,涵蓋表格、表單、佈局、對話框、穿梭框等
- 🧪 **完整測試** - 單元測試 + E2E 測試,確保組件穩定性
- 📚 **詳細文檔** - 完整的 API 文檔和使用示例
## 📦 安裝
使用您喜歡的包管理器安裝:
```bash
# npm
npm install rayyy-vue-table-components
# yarn
yarn add rayyy-vue-table-components
# pnpm
pnpm add rayyy-vue-table-components
```
> **注意**: 本組件庫需要 Vue 3.0+、Element Plus 和 vue-i18n (>=10.0.0) 作為對等依賴。
## 🚀 快速開始
### 完整引入
在 `main.ts` 中完整引入所有組件:
```typescript
import { createApp } from 'vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import VueTableComponents from 'rayyy-vue-table-components'
import 'rayyy-vue-table-components/styles'
import App from './App.vue'
const app = createApp(App)
// 安裝 Element Plus(可自定義語系)
app.use(ElementPlus, {
locale: zhTw // 設定繁體中文
})
// 安裝組件庫
app.use(VueTableComponents)
app.mount('#app')
```
### 語系設定
組件庫依賴 Element Plus,請在安裝 Element Plus 時設定語系:
```typescript
import { createApp } from 'vue'
import ElementPlus from 'element-plus'
import zhTw from 'element-plus/es/locale/lang/zh-tw'
import en from 'element-plus/es/locale/lang/en'
import VueTableComponents from 'rayyy-vue-table-components'
const app = createApp(App)
// 使用繁體中文
app.use(ElementPlus, {
locale: zhTw
})
// 或使用英文
app.use(ElementPlus, {
locale: en
})
app.use(VueTableComponents)
app.mount('#app')
```
### 國際化 (i18n) 設定
組件庫支援國際化,需要與外部專案的 `vue-i18n` 整合。**重要**:組件庫提供翻譯檔案,需要外部專案合併使用:
```typescript
import { createApp } from 'vue'
import { createI18n } from 'vue-i18n'
import ElementPlus from 'element-plus'
import VueTableComponents, { messages as componentMessages } from 'rayyy-vue-table-components'
const app = createApp(App)
// 建立 i18n 實例,合併組件庫的翻譯
const i18n = createI18n({
legacy: false,
locale: 'zh-TW',
fallbackLocale: 'zh-TW',
messages: {
// 合併組件庫的翻譯
'zh-TW': {
...componentMessages['zh-TW'],
// 可以添加您自己的翻譯
'custom.key': '自定義翻譯'
},
'en-US': {
...componentMessages['en-US'],
// 可以添加您自己的翻譯
'custom.key': 'Custom Translation'
}
}
})
app.use(i18n)
app.use(ElementPlus)
app.use(VueTableComponents)
app.mount('#app')
```
**支援的語系:**
- `zh-TW` - 繁體中文(預設)
- `en-US` - 英文
**導入翻譯檔案:**
```typescript
// 導入組件庫的翻譯
import { messages as componentMessages } from 'rayyy-vue-table-components/locales'
// 導入特定語系
import { zhTW, enUS } from 'rayyy-vue-table-components/locales'
// 導入類型
import type { LocaleType } from 'rayyy-vue-table-components/locales'
```
### 按需引入
如果您只想使用部分組件,可以按需引入:
```vue
<script setup>
import {
SortTable,
TransferDialog,
TransferItem,
BaseBtn,
SearchableListPanel,
} from 'rayyy-vue-table-components'
</script>
<template>
<div>
<BaseBtn>按鈕</BaseBtn>
<SortTable :data="tableData" />
<!-- 其他組件... -->
</div>
</template>
```
### Hello World
創建您的第一個表格:
```vue
<template>
<BaseTable
:data="tableData"
:columns="columns"
:loading="loading"
/>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { BaseTable } from 'rayyy-vue-table-components'
import type { TableColumn } from 'rayyy-vue-table-components'
interface User {
id: number
name: string
email: string
}
const loading = ref(false)
const tableData = ref<User[]>([
{ id: 1, name: '張三', email: 'zhangsan@example.com' },
{ id: 2, name: '李四', email: 'lisi@example.com' }
])
const columns: TableColumn<User>[] = [
{ prop: 'id', label: 'ID', width: 80 },
{ prop: 'name', label: '姓名' },
{ prop: 'email', label: '郵箱' }
]
</script>
```
## 🎨 樣式配置
本組件庫提供多種靈活的樣式導入方式:
### 完整樣式導入(推薦)
```typescript
// main.ts
import 'element-plus/dist/index.css'
import 'rayyy-vue-table-components/styles'
```
### 自定義主題
```scss
// styles.scss
@import 'element-plus/dist/index.css';
@import 'rayyy-vue-table-components/styles/element';
```
### TypeScript 樣式工具
```vue
<template>
<!-- 直接使用預定義的樣式類別 -->
<div class="table-cell bg-blue-20">被駁回的單元格</div>
<div class="table-header">標題行</div>
</template>
```
## 📚 組件示例
### 🗂️ 表格組件
#### BaseTable - 基礎數據表格
基礎的數據表格組件,支援排序、選擇、自定義列等功能。
<details>
<summary>基本用法</summary>
```vue
<template>
<BaseTable
:data="tableData"
:columns="columns"
:loading="loading"
@column-sort-change="handleSortChange"
/>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { BaseTable } from 'rayyy-vue-table-components'
import type { TableColumn, SortChangValue } from 'rayyy-vue-table-components'
interface User {
id: number
name: string
email: string
age: number
}
const loading = ref(false)
const tableData = ref<User[]>([
{ id: 1, name: '張三', email: 'zhangsan@example.com', age: 30 },
{ id: 2, name: '李四', email: 'lisi@example.com', age: 25 }
])
const columns: TableColumn<User>[] = [
{ prop: 'id', label: 'ID', width: 80 },
{ prop: 'name', label: '姓名', sortable: true },
{ prop: 'email', label: '郵箱' },
{ prop: 'age', label: '年齡', sortable: true }
]
const handleSortChange = (sortInfo: SortChangValue<User>) => {
console.log('排序變更:', sortInfo)
}
</script>
```
</details>
<details>
<summary>帶選擇和合計的表格</summary>
```vue
<template>
<BaseTable
:data="tableData"
:columns="columns"
:show-selection="true"
:show-summary="true"
:summary-method="summaryMethod"
@selection-change="handleSelectionChange"
/>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { BaseTable } from 'rayyy-vue-table-components'
import type { TableColumn } from 'rayyy-vue-table-components'
interface Product {
id: number
name: string
price: number
quantity: number
}
const tableData = ref<Product[]>([
{ id: 1, name: '產品A', price: 100, quantity: 5 },
{ id: 2, name: '產品B', price: 200, quantity: 3 }
])
const columns: TableColumn<Product>[] = [
{ prop: 'id', label: 'ID', width: 80 },
{ prop: 'name', label: '產品名稱' },
{ prop: 'price', label: '單價' },
{ prop: 'quantity', label: '數量' }
]
const summaryMethod = ({ columns, data }: any) => {
const sums: string[] = []
columns.forEach((column: any, index: number) => {
if (index === 0) {
sums[index] = '總計'
} else if (column.property === 'price') {
const values = data.map((item: Product) => Number(item.price))
sums[index] = values.reduce((prev, curr) => prev + curr, 0).toString()
} else if (column.property === 'quantity') {
const values = data.map((item: Product) => Number(item.quantity))
sums[index] = values.reduce((prev, curr) => prev + curr, 0).toString()
} else {
sums[index] = ''
}
})
return sums
}
const handleSelectionChange = (selection: Product[]) => {
console.log('選中項:', selection)
}
</script>
```
</details>
#### SortTable - 排序表格
支援多列排序的高級表格組件。
<details>
<summary>基本用法</summary>
```vue
<template>
<SortTable
:data="tableData"
:columns="columns"
:loading="loading"
@sort-change="handleSortChange"
/>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { SortTable } from 'rayyy-vue-table-components'
import type { TableColumn, SortInfo } from 'rayyy-vue-table-components'
interface User {
id: number
name: string
email: string
age: number
score: number
}
const loading = ref(false)
const tableData = ref<User[]>([
{ id: 1, name: '張三', email: 'zhangsan@example.com', age: 30, score: 85 },
{ id: 2, name: '李四', email: 'lisi@example.com', age: 25, score: 92 }
])
const columns: TableColumn<User>[] = [
{ prop: 'id', label: 'ID', width: 80 },
{ prop: 'name', label: '姓名', sortable: true },
{ prop: 'email', label: '郵箱' },
{ prop: 'age', label: '年齡', sortable: true },
{ prop: 'score', label: '分數', sortable: true }
]
const handleSortChange = (sortInfo: SortInfo<User>) => {
console.log('排序變更:', sortInfo)
}
</script>
```
</details>
#### TitleTable - 標題表格
帶標題和操作按鈕的表格組件。
<details>
<summary>基本用法</summary>
```vue
<template>
<TitleTable
title="用戶列表"
:data="tableData"
:columns="columns"
:loading="loading"
@add="handleAdd"
@export="handleExport"
/>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { TitleTable } from 'rayyy-vue-table-components'
import type { TableColumn } from 'rayyy-vue-table-components'
interface User {
id: number
name: string
email: string
}
const loading = ref(false)
const tableData = ref<User[]>([
{ id: 1, name: '張三', email: 'zhangsan@example.com' },
{ id: 2, name: '李四', email: 'lisi@example.com' }
])
const columns: TableColumn<User>[] = [
{ prop: 'id', label: 'ID', width: 80 },
{ prop: 'name', label: '姓名' },
{ prop: 'email', label: '郵箱' }
]
const handleAdd = () => {
console.log('新增用戶')
}
const handleExport = () => {
console.log('導出數據')
}
</script>
```
</details>
### 🎛️ 表單組件
#### BaseInput - 基礎輸入框
增強的輸入框組件,支援多種類型和驗證功能。
<details>
<summary>基本用法</summary>
```vue
<template>
<div class="space-y-4">
<BaseInput
v-model="inputValue"
placeholder="請輸入內容"
:clearable="true"
/>
<BaseInput
v-model="passwordValue"
type="password"
placeholder="請輸入密碼"
show-password
/>
<BaseInput
v-model="emailValue"
type="email"
placeholder="請輸入郵箱"
:validate="validateEmail"
/>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { BaseInput } from 'rayyy-vue-table-components'
const inputValue = ref('')
const passwordValue = ref('')
const emailValue = ref('')
const validateEmail = (value: string) => {
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
return emailRegex.test(value) || '請輸入有效的郵箱地址'
}
</script>
```
</details>
### 🎨 交互組件
#### BaseBtn - 按鈕組件
增強的按鈕組件,支援多種樣式和狀態。
<details>
<summary>基本用法</summary>
```vue
<template>
<div class="button-group">
<BaseBtn type="primary" @click="handleClick">主要按鈕</BaseBtn>
<BaseBtn type="success" :loading="loading">成功按鈕</BaseBtn>
<BaseBtn type="warning" plain>樸素按鈕</BaseBtn>
<BaseBtn type="danger" disabled>禁用按鈕</BaseBtn>
<BaseBtn type="info" link>文字按鈕</BaseBtn>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { BaseBtn } from 'rayyy-vue-table-components'
const loading = ref(false)
const handleClick = () => {
loading.value = true
setTimeout(() => {
loading.value = false
}, 2000)
}
</script>
<style scoped>
.button-group {
display: flex;
gap: 12px;
flex-wrap: wrap;
}
</style>
```
</details>
#### SearchBar - 搜尋欄組件
功能豐富的搜尋欄組件,支援即時搜尋和搜尋建議。
<details>
<summary>基本用法</summary>
```vue
<template>
<SearchBar
v-model="searchKeyword"
placeholder="搜尋用戶、郵箱或電話..."
:suggestions="suggestions"
@search="handleSearch"
@suggestion-click="handleSuggestionClick"
/>
</template>
<script setup lang="ts">
import { ref, computed } from 'vue'
import { SearchBar } from 'rayyy-vue-table-components'
const searchKeyword = ref('')
const allSuggestions = ref([
'張三', '李四', '王五', '趙六'
])
const suggestions = computed(() => {
if (!searchKeyword.value) return []
return allSuggestions.value.filter(item =>
item.includes(searchKeyword.value)
)
})
const handleSearch = (keyword: string) => {
console.log('搜尋關鍵字:', keyword)
}
const handleSuggestionClick = (suggestion: string) => {
searchKeyword.value = suggestion
}
</script>
```
</details>
### 💬 對話框組件
#### BaseDialog - 基礎對話框
靈活的對話框組件,支援多種配置選項。
<details>
<summary>基本用法</summary>
```vue
<template>
<div>
<BaseBtn type="primary" @click="showDialog = true">
打開對話框
</BaseBtn>
<BaseDialog
v-model="showDialog"
title="確認操作"
sub-title="此操作將永久刪除該文件,是否繼續?"
:is-warning="true"
@confirm="handleConfirm"
@cancel="handleCancel"
>
<p>這是對話框的內容區域,您可以放置任何內容。</p>
</BaseDialog>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { BaseBtn, BaseDialog } from 'rayyy-vue-table-components'
const showDialog = ref(false)
const handleConfirm = () => {
console.log('確認操作')
showDialog.value = false
}
const handleCancel = () => {
console.log('取消操作')
showDialog.value = false
}
</script>
```
</details>
#### BaseWaringDialog - 警告對話框
專門用於警告和確認操作的對話框組件。
<details>
<summary>基本用法</summary>
```vue
<template>
<div>
<BaseBtn type="danger" @click="showWarningDialog = true">
刪除項目
</BaseBtn>
<BaseWaringDialog
v-model="showWarningDialog"
title="警告"
sub-title="此操作無法復原,確定要刪除嗎?"
@confirm="handleConfirm"
@cancel="handleCancel"
/>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { BaseBtn, BaseWaringDialog } from 'rayyy-vue-table-components'
const showWarningDialog = ref(false)
const handleConfirm = () => {
console.log('確認刪除')
showWarningDialog.value = false
}
const handleCancel = () => {
console.log('取消刪除')
showWarningDialog.value = false
}
</script>
```
</details>
### 🏗️ 佈局組件
#### MainPanel - 主面板組件
靈活的主面板組件,提供標題、返回按鈕和可自定義高度的滾動區域。
<details>
<summary>基本用法</summary>
```vue
<template>
<MainPanel
title="用戶管理"
:show-back="true"
max-height="calc(100vh-200px)"
>
<template #searchBar>
<SearchBar @search="handleSearch" />
</template>
<template #main>
<BaseTable
:data="tableData"
:columns="columns"
:loading="loading"
/>
</template>
<template #footer>
<el-pagination
v-model:current-page="currentPage"
v-model:page-size="pageSize"
:total="total"
layout="total, sizes, prev, pager, next, jumper"
/>
</template>
</MainPanel>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { MainPanel, SearchBar, BaseTable } from 'rayyy-vue-table-components'
import type { TableColumn } from 'rayyy-vue-table-components'
interface User {
id: number
name: string
email: string
}
const loading = ref(false)
const currentPage = ref(1)
const pageSize = ref(10)
const total = ref(100)
const tableData = ref<User[]>([
{ id: 1, name: '張三', email: 'zhangsan@example.com' },
{ id: 2, name: '李四', email: 'lisi@example.com' }
])
const columns: TableColumn<User>[] = [
{ prop: 'id', label: 'ID', width: 80 },
{ prop: 'name', label: '姓名' },
{ prop: 'email', label: '郵箱' }
]
const handleSearch = (keyword: string) => {
console.log('搜尋關鍵字:', keyword)
}
</script>
```
</details>
#### DetailLayout - 詳細頁面佈局
專門用於詳細頁面的佈局組件,支援編輯模式和只讀模式切換。
<details>
<summary>基本用法</summary>
```vue
<template>
<DetailLayout
title="用戶詳細信息"
:editable="isEditable"
:loading="loading"
@save="handleSave"
@cancel="handleCancel"
@back="handleBack"
>
<template #header>
<div class="flex items-center justify-between">
<h1 class="text-2xl font-bold">用戶管理</h1>
<BaseBtn
type="primary"
@click="toggleEdit"
>
{{ isEditable ? '保存' : '編輯' }}
</BaseBtn>
</div>
</template>
<template #main>
<div class="space-y-6">
<div class="grid grid-cols-2 gap-4">
<BaseInput
v-model="userForm.name"
label="姓名"
:disabled="!isEditable"
/>
<BaseInput
v-model="userForm.email"
label="郵箱"
type="email"
:disabled="!isEditable"
/>
</div>
</div>
</template>
</DetailLayout>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { DetailLayout, BaseBtn, BaseInput } from 'rayyy-vue-table-components'
const isEditable = ref(false)
const loading = ref(false)
const userForm = ref({
name: '張三',
email: 'zhangsan@example.com'
})
const toggleEdit = () => {
isEditable.value = !isEditable.value
}
const handleSave = async () => {
loading.value = true
// 模擬保存操作
await new Promise(resolve => setTimeout(resolve, 1000))
loading.value = false
isEditable.value = false
}
const handleCancel = () => {
isEditable.value = false
}
const handleBack = () => {
// 返回上一頁
console.log('返回上一頁')
}
</script>
```
</details>
#### FilterLayout - 篩選頁面佈局
專門用於篩選頁面的佈局組件,支援自定義篩選表單。
<details>
<summary>基本用法</summary>
```vue
<template>
<FilterLayout
main-title="用戶管理"
filter-title="篩選條件"
@submit="handleFilterSubmit"
@reset="handleFilterReset"
>
<template #filter-form>
<div class="grid grid-cols-1 md:grid-cols-3 gap-4">
<BaseInput
v-model="filterForm.keyword"
label="關鍵字"
placeholder="搜尋姓名或郵箱"
/>
<BaseInput
v-model="filterForm.dateRange"
label="創建時間"
type="daterange"
/>
</div>
</template>
</FilterLayout>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { FilterLayout, BaseInput } from 'rayyy-vue-table-components'
const filterForm = ref({
keyword: '',
dateRange: []
})
const handleFilterSubmit = () => {
console.log('篩選條件:', filterForm.value)
}
const handleFilterReset = () => {
filterForm.value = {
keyword: '',
dateRange: []
}
}
</script>
```
</details>
#### SearchableListPanel - 整合式搜尋面板
整合搜尋、篩選、分頁功能的綜合面板組件。**支援 locale prop 來覆寫 i18n 設定**。
<details>
<summary>基本用法</summary>
```vue
<template>
<SearchableListPanel
title="用戶列表"
:data="tableData"
:columns="columns"
:loading="loading"
:pagination="pagination"
@search="handleSearch"
@filter="handleFilter"
@page-change="handlePageChange"
>
<template #firstButton>
<BaseBtn type="primary" @click="handleAdd">
新增用戶
</BaseBtn>
</template>
<template #customButton>
<BaseBtn type="success" @click="handleExport">
導出數據
</BaseBtn>
</template>
<template #lastButton>
<BaseBtn type="warning" @click="handleBatch">
批量操作
</BaseBtn>
</template>
</SearchableListPanel>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { SearchableListPanel, BaseBtn } from 'rayyy-vue-table-components'
import type { TableColumn } from 'rayyy-vue-table-components'
interface User {
id: number
name: string
email: string
status: string
}
const loading = ref(false)
const tableData = ref<User[]>([
{ id: 1, name: '張三', email: 'zhangsan@example.com', status: 'active' },
{ id: 2, name: '李四', email: 'lisi@example.com', status: 'inactive' }
])
const columns: TableColumn<User>[] = [
{ prop: 'id', label: 'ID', width: 80 },
{ prop: 'name', label: '姓名' },
{ prop: 'email', label: '郵箱' },
{ prop: 'status', label: '狀態' }
]
const pagination = ref({
current: 1,
pageSize: 10,
total: 100
})
const handleSearch = (keyword: string) => {
console.log('搜尋:', keyword)
}
const handleFilter = (filters: Record<string, any>) => {
console.log('篩選:', filters)
}
const handlePageChange = (page: number, pageSize: number) => {
console.log('分頁變更:', page, pageSize)
}
const handleAdd = () => {
console.log('新增用戶')
}
const handleExport = () => {
console.log('導出數據')
}
const handleBatch = () => {
console.log('批量操作')
}
</script>
```
</details>
<details>
<summary>使用 locale prop 覆寫 i18n</summary>
```vue
<template>
<SearchableListPanel
title="User List"
:data="tableData"
:columns="columns"
:loading="loading"
:pagination="pagination"
:locale="elementLocale"
@search="handleSearch"
/>
</template>
<script setup lang="ts">
import { ref, computed } from 'vue'
import { SearchableListPanel } from 'rayyy-vue-table-components'
import en from 'element-plus/es/locale/lang/en'
import zhTw from 'element-plus/es/locale/lang/zh-tw'
const currentLocale = ref('zh-TW')
// 根據當前語系選擇 Element Plus locale
const elementLocale = computed(() => {
return currentLocale.value === 'zh-TW' ? zhTw : en
})
// 切換語系
const switchLocale = () => {
currentLocale.value = currentLocale.value === 'zh-TW' ? 'en-US' : 'zh-TW'
}
// 其他組件邏輯...
</script>
```
</details>
#### FunctionHeader - 功能頁面標題
提供頁面標題、麵包屑和操作按鈕的功能標題組件。
<details>
<summary>基本用法</summary>
```vue
<template>
<FunctionHeader
title="用戶管理"
sub-title="管理系統用戶信息"
:breadcrumbs="breadcrumbs"
>
<template #actions>
<BaseBtn type="primary">新增用戶</BaseBtn>
<BaseBtn type="default">導出數據</BaseBtn>
</template>
</FunctionHeader>
</template>
<script setup lang="ts">
import { FunctionHeader, BaseBtn } from 'rayyy-vue-table-components'
const breadcrumbs = [
{ label: '首頁', path: '/' },
{ label: '系統管理', path: '/system' },
{ label: '用戶管理' }
]
</script>
```
</details>
### 🔄 轉移組件
#### TransferDialog - 穿梭框對話框
用於表格列配置的穿梭框組件,支援拖拽排序。
<details>
<summary>基本用法</summary>
```vue
<template>
<div>
<BaseBtn @click="showTransferDialog = true">配置表格列</BaseBtn>
<TransferDialog
v-model="showTransferDialog"
:columns-value="tableColumns"
transfer-title="配置表格列"
@update:submit="handleColumnSubmit"
>
<template #list-container="{ columns, clickItemProp, handleItemEvents, handleMousedown }">
<draggable :list="columns" item-key="prop" delay="200">
<template #item="{ element, index }">
<TransferItem
:columns-value="element"
:columns-index="index"
:columns-len="columns.length"
:class="{
'transfer-active-bg': element.checkActive,
'transfer-active-border': clickItemProp === element.prop,
}"
@mousedown="handleMousedown(element.prop || '')"
@update:toTop="handleItemEvents.toTop(index)"
@update:toBottom="handleItemEvents.toBottom(index)"
@update:toPre="handleItemEvents.toPre(index)"
@update:toNext="handleItemEvents.toNext(index)"
/>
</template>
</draggable>
</template>
</TransferDialog>
<!-- 使用配置後的表格 -->
<BaseTable
:data="tableData"
:columns="visibleColumns"
style="margin-top: 20px"
/>
</div>
</template>
<script setup lang="ts">
import { ref, computed } from 'vue'
import draggable from 'vuedraggable'
import { BaseBtn, BaseTable, TransferDialog, TransferItem } from 'rayyy-vue-table-components'
import type { TableColumn } from 'rayyy-vue-table-components'
interface User {
id: number
name: string
email: string
age: number
}
const showTransferDialog = ref(false)
const tableData = ref<User[]>([
{ id: 1, name: '張三', email: 'zhangsan@example.com', age: 30 },
{ id: 2, name: '李四', email: 'lisi@example.com', age: 25 }
])
const tableColumns = ref<TableColumn<User>[]>([
{ prop: 'id', label: 'ID', width: 80, checkActive: true },
{ prop: 'name', label: '姓名', checkActive: true },
{ prop: 'email', label: '郵箱', checkActive: true },
{ prop: 'age', label: '年齡', checkActive: false }
])
const visibleColumns = computed(() =>
tableColumns.value.filter(col => col.checkActive)
)
const handleColumnSubmit = (newColumns: TableColumn<User>[]) => {
tableColumns.value = newColumns
showTransferDialog.value = false
}
</script>
```
</details>
## 🔧 API 參考
### BaseTable
基礎表格組件,提供完整的數據展示和交互功能。
#### Props
| 屬性 | 類型 | 默認值 | 說明 |
|------|------|--------|------|
| `data` | `T[]` | `[]` | 表格數據 |
| `columns` | `TableColumn<T>[]` | `[]` | 表格列配置 |
| `loading` | `boolean` | `false` | 加載狀態 |
| `showSelection` | `boolean` | `false` | 是否顯示選擇列 |
| `showSummary` | `boolean` | `false` | 是否顯示合計行 |
| `showOverFlowTooltip` | `boolean` | `false` | 是否顯示溢出提示 |
| `summaryMethod` | `SummaryMethod<T>` | - | 合計行計算方法 |
| `baseTableRowClassName` | `RowClassNameGetter<T>` | - | 行樣式類名函數 |
| `showCheckBtn` | `boolean` | `false` | 是否顯示查看按鈕 |
| `showEditBtn` | `boolean` | `false` | 是否顯示編輯按鈕 |
#### Events
| 事件名 | 參數 | 說明 |
|--------|------|------|
| `selection-change` | `selection: T[]` | 選擇項變更時觸發 |
| `current-change` | `currentRow: T \| null` | 當前行變更時觸發 |
| `cell-click` | `column: TableColumn<T>, row: T` | 單元格點擊時觸發 |
| `column-sort-change` | `value: SortChangValue<T>` | 列排序變更時觸發 |
| `click:checkRow` | `row: T` | 查看按鈕點擊時觸發 |
| `click:editRow` | `row: T` | 編輯按鈕點擊時觸發 |
#### Slots
| 插槽名 | 參數 | 說明 |
|--------|------|------|
| `empty` | - | 空數據時的內容 |
| `append` | - | 插入至表格最後一行之後的內容 |
---
### BaseBtn
增強的按鈕組件,基於 Element Plus Button 擴展。
#### Props
| 屬性 | 類型 | 默認值 | 說明 |
|------|------|--------|------|
| `text` | `string` | - | 按鈕文字 |
| `type` | `ButtonType` | `'default'` | 按鈕類型 |
| `size` | `ComponentSize` | `'default'` | 按鈕尺寸 |
| `plain` | `boolean` | `false` | 是否為樸素按鈕 |
| `disabled` | `boolean` | `false` | 是否禁用 |
| `loading` | `boolean` | `false` | 是否顯示加載狀態 |
| `icon` | `Component` | - | 圖標組件 |
| `link` | `boolean` | `false` | 是否為文字按鈕 |
| `isFill` | `boolean` | `false` | 是否為填充樣式 |
#### Events
| 事件名 | 參數 | 說明 |
|--------|------|------|
| `click` | `event: MouseEvent` | 點擊按鈕時觸發 |
#### 類型定義
```typescript
type ButtonType = 'default' | 'primary' | 'success' | 'warning' | 'info' | 'danger'
type ComponentSize = 'default' | 'small' | 'large'
```
---
### BaseInput
增強的輸入框組件,支援多種類型和驗證功能。
#### Props
| 屬性 | 類型 | 默認值 | 說明 |
|------|------|--------|------|
| `modelValue` | `string \| number \| null` | - | 輸入值 |
| `placeholder` | `string` | - | 佔位符 |
| `type` | `string` | `'text'` | 輸入框類型 |
| `class` | `string \| object` | - | 自定義類名 |
| `showPassword` | `boolean` | `false` | 是否顯示密碼切換按鈕 |
| `disabled` | `boolean` | `false` | 是否禁用 |
| `readonly` | `boolean` | `false` | 是否只讀 |
| `maxlength` | `string \| number` | - | 最大長度 |
| `autocomplete` | `'on' \| 'off'` | - | 自動完成 |
| `showSearch` | `boolean` | `false` | 是否顯示搜尋圖標 |
#### Events
| 事件名 | 參數 | 說明 |
|--------|------|------|
| `update:modelValue` | `value: string \| number \| null` | 輸入值變更時觸發 |
| `update:clearValue` | - | 清除值時觸發 |
---
### BaseDialog
靈活的對話框組件,支援多種配置選項。
#### Props
| 屬性 | 類型 | 默認值 | 說明 |
|------|------|--------|------|
| `modelValue` | `boolean` | - | 對話框顯示狀態 |
| `title` | `string` | - | 對話框標題 |
| `subTitle` | `string` | - | 副標題 |
| `customWidth` | `string` | - | 自定義寬度 |
| `isWarning` | `boolean` | `false` | 是否為警告對話框 |
| `isPrimary` | `boolean` | `false` | 是否為主要對話框 |
| `bodyLoading` | `boolean` | `false` | 內容區域加載狀態 |
| `submitLoading` | `boolean` | `false` | 提交按鈕加載狀態 |
#### Events
| 事件名 | 參數 | 說明 |
|--------|------|------|
| `update:modelValue` | `value: boolean` | 對話框顯示狀態變更 |
| `confirm` | - | 確認按鈕點擊時觸發 |
| `cancel` | - | 取消按鈕點擊時觸發 |
#### Slots
| 插槽名 | 參數 | 說明 |
|--------|------|------|
| `default` | - | 對話框內容 |
| `footer` | - | 自定義底部按鈕區域 |
---
### BaseWaringDialog
警告對話框組件,專門用於警告和確認操作。
#### Props
| 屬性 | 類型 | 默認值 | 說明 |
|------|------|--------|------|
| `modelValue` | `boolean` | - | 對話框顯示狀態 |
| `title` | `string` | - | 對話框標題 |
| `subTitle` | `string` | - | 副標題 |
| `customWidth` | `string` | - | 自定義寬度 |
#### Events
| 事件名 | 參數 | 說明 |
|--------|------|------|
| `update:modelValue` | `value: boolean` | 對話框顯示狀態變更 |
| `confirm` | - | 確認按鈕點擊時觸發 |
| `cancel` | - | 取消按鈕點擊時觸發 |
---
### SortTable
支援多列排序的高級表格組件。
#### Props
| 屬性 | 類型 | 默認值 | 說明 |
|------|------|--------|------|
| `data` | `T[]` | `[]` | 表格數據 |
| `columns` | `TableColumn<T>[]` | `[]` | 表格列配置 |
| `tableTitle` | `string` | - | 表格標題 |
| `showSelection` | `boolean` | `false` | 是否顯示選擇列 |
| `loading` | `boolean` | `false` | 加載狀態 |
| `showSummary` | `boolean` | `false` | 是否顯示合計行 |
| `showOverFlowTooltip` | `boolean` | `false` | 是否顯示溢出提示 |
| `summaryMethod` | `SummaryMethod<T>` | - | 合計行計算方法 |
| `sortTableRowClassName` | `RowClassNameGetter<T>` | - | 行樣式類名函數 |
| `showCheckBtn` | `boolean` | `false` | 是否顯示查看按鈕 |
| `showEditBtn` | `boolean` | `false` | 是否顯示編輯按鈕 |
#### Events
| 事件名 | 參數 | 說明 |
|--------|------|------|
| `open:transfer` | - | 打開轉移對話框時觸發 |
| `click:downloadExcelFile` | - | 下載 Excel 檔案時觸發 |
| `update:selectRow` | `value: T[]` | 更新選擇行時觸發 |
| `click:cell` | `column: TableColumn<T>, row: T` | 單元格點擊時觸發 |
| `sort-change` | `sortInfo: SortInfo<T>` | 排序變更時觸發 |
---
### TitleTable
帶標題和操作按鈕的表格組件。
#### Props
| 屬性 | 類型 | 默認值 | 說明 |
|------|------|--------|------|
| `title` | `string` | - | 表格標題 |
| `data` | `T[]` | `[]` | 表格數據 |
| `columns` | `TableColumn<T>[]` | `[]` | 表格列配置 |
| `loading` | `boolean` | `false` | 加載狀態 |
| `showSelection` | `boolean` | `false` | 是否顯示選擇列 |
| `showSummary` | `boolean` | `false` | 是否顯示合計行 |
| `showOverFlowTooltip` | `boolean` | `false` | 是否顯示溢出提示 |
| `summaryMethod` | `SummaryMethod<T>` | - | 合計行計算方法 |
| `titleTableRowClassName` | `RowClassNameGetter<T>` | - | 行樣式類名函數 |
| `showCheckBtn` | `boolean` | `false` | 是否顯示查看按鈕 |
| `showEditBtn` | `boolean` | `false` | 是否顯示編輯按鈕 |
#### Events
| 事件名 | 參數 | 說明 |
|--------|------|------|
| `add` | - | 新增按鈕點擊時觸發 |
| `export` | - | 導出按鈕點擊時觸發 |
| `update:selectRow` | `value: T[]` | 更新選擇行時觸發 |
| `click:cell` | `column: TableColumn<T>, row: T` | 單元格點擊時觸發 |
| `sort-change` | `sortInfo: SortInfo<T>` | 排序變更時觸發 |
---
### SearchBar
功能豐富的搜尋欄組件,支援即時搜尋和搜尋建議。
#### Props
| 屬性 | 類型 | 默認值 | 說明 |
|------|------|--------|------|
| `showSearch` | `boolean` | `false` | 是否顯示搜尋功能 |
#### Events
| 事件名 | 參數 | 說明 |
|--------|------|------|
| `keydown:enter` | `data: string` | 按下 Enter 鍵時觸發 |
| `update:clear` | - | 清除時觸發 |
| `update:resetFilter` | - | 重置篩選時觸發 |
---
### TransferDialog
用於表格列配置的穿梭框組件。
#### Props
| 屬性 | 類型 | 默認值 | 說明 |
|------|------|--------|------|
| `modelValue` | `boolean` | - | 對話框顯示狀態 |
| `columnsValue` | `TableColumn<T>[]` | `[]` | 表格列配置 |
| `transferTitle` | `string` | - | 對話框標題 |
#### Events
| 事件名 | 參數 | 說明 |
|--------|------|------|
| `update:modelValue` | `value: boolean` | 對話框顯示狀態變更 |
| `update:submit` | `columns: TableColumn<T>[]` | 提交列配置時觸發 |
#### Slots
| 插槽名 | 參數 | 說明 |
|--------|------|------|
| `list-container` | `ListContainerSlotProps` | 自定義列表容器 |
#### 類型定義
```typescript
interface ListContainerSlotProps<T = any> {
columns: TableColumn<T>[]
clickItemProp: string
handleItemEvents: {
toTop: (index: number) => void
toBottom: (index: number) => void
toPre: (index: number) => void
toNext: (index: number) => void
}
handleMousedown: (prop: string) => void
}
```
---
### TransferItem
轉移項目組件,用於 TransferDialog 中。
#### Props
| 屬性 | 類型 | 默認值 | 說明 |
|------|------|--------|------|
| `columnsValue` | `TableColumn<T>` | - | 列配置對象 |
| `columnsIndex` | `number` | - | 列索引 |
| `columnsLen` | `number` | - | 列總數 |
#### Events
| 事件名 | 參數 | 說明 |
|--------|------|------|
| `mousedown` | `prop: string` | 滑鼠按下時觸發 |
| `update:toTop` | `index: number` | 移至頂部時觸發 |
| `update:toBottom` | `index: number` | 移至底部時觸發 |
| `update:toPre` | `index: number` | 移至前一位時觸發 |
| `update:toNext` | `index: number` | 移至下一位時觸發 |
---
### MainPanel
主面板組件,提供標題、返回按鈕和可自定義高度的滾動區域。
#### Props
| 屬性 | 類型 | 默認值 | 說明 |
|------|------|--------|------|
| `title` | `string` | `''` | 面板標題 |
| `showBack` | `boolean \| string \| object` | `false` | 是否顯示返回按鈕 |
| `depth` | `number` | `1` | 返回深度 |
| `maxHeight` | `string` | `'calc(100vh-120px)'` | 滾動區域最大高度 |
#### Events
| 事件名 | 參數 | 說明 |
|--------|------|------|
| `back` | `payload: { path?: string; [key: string]: unknown }` | 返回按鈕點擊時觸發 |
#### Slots
| 插槽名 | 參數 | 說明 |
|--------|------|------|
| `searchBar` | - | 搜尋欄區域 |
| `main` | - | 主要內容區域 |
| `footer` | - | 底部區域(如分頁器) |
---
### SearchableListPanel
整合式搜尋、篩選、分頁組件。**支援 locale prop 來覆寫 i18n 設定**。
#### Props
| 屬性 | 類型 | 默認值 | 說明 |
|------|------|--------|------|
| `title` | `string` | - | 面板標題 |
| `pagination` | `Pager` | - | 分頁配置 |
| `showBack` | `boolean \| string \| object` | `false` | 是否顯示返回按鈕 |
| `showSearch` | `boolean` | `false` | 是否顯示搜尋功能 |
| `pageSizeList` | `number[]` | `[10, 25, 50, 100, 200]` | 頁面大小選項 |
| `showPagination` | `boolean` | - | 是否顯示分頁器 |
| `locale` | `Language` | - | **Element Plus 語言設定,用於覆寫 i18n** |
#### Events
| 事件名 | 參數 | 說明 |
|--------|------|------|
| `search` | `data: string \| null` | 搜尋時觸發 |
| `updatePage` | `page: number` | 頁碼變更時觸發 |
| `updatePageSize` | `limit: number` | 頁面大小變更時觸發 |
| `click:back` | - | 返回按鈕點擊時觸發 |
#### Slots
| 插槽名 | 參數 | 說明 |
|--------|------|------|
| `firstButton` | - | 第一個按鈕插槽 |
| `customButton` | - | 自定義按鈕插槽 |
| `lastButton` | - | 最後一個按鈕插槽 |
| `filterButton` | - | 篩選按鈕插槽 |
| `main` | - | 主要內容區域 |
---
### DetailLayout
詳細頁面佈局組件,支援編輯模式和只讀模式切換。
#### Props
| 屬性 | 類型 | 默認值 | 說明 |
|------|------|--------|------|
| `title` | `string` | - | 頁面標題 |
| `editable` | `boolean` | `false` | 是否可編輯 |
| `loading` | `boolean` | `false` | 加載狀態 |
#### Events
| 事件名 | 參數 | 說明 |
|--------|------|------|
| `save` | - | 保存時觸發 |
| `cancel` | - | 取消時觸發 |
| `back` | - | 返回時觸發 |
#### Slots
| 插槽名 | 參數 | 說明 |
|--------|------|------|
| `header` | - | 標題區域 |
| `main` | - | 主要內容區域 |
---
### FilterLayout
篩選頁面佈局組件,支援自定義篩選表單。
#### Props
| 屬性 | 類型 | 默認值 | 說明 |
|------|------|--------|------|
| `mainTitle` | `string` | - | 主要標題 |
| `filterTitle` | `string` | - | 篩選標題 |
#### Events
| 事件名 | 參數 | 說明 |
|--------|------|------|
| `submit` | - | 提交篩選時觸發 |
| `reset` | - | 重置篩選時觸發 |
#### Slots
| 插槽名 | 參數 | 說明 |
|--------|------|------|
| `filter-form` | - | 篩選表單內容 |
---
### FunctionHeader
功能頁面標題組件,提供頁面標題、麵包屑和操作按鈕。
#### Props
| 屬性 | 類型 | 默認值 | 說明 |
|------|------|--------|------|
| `title` | `string` | - | 頁面標題 |
| `subTitle` | `string` | - | 頁面副標題 |
| `breadcrumbs` | `BreadcrumbItem[]` | `[]` | 麵包屑配置 |
#### Slots
| 插槽名 | 參數 | 說明 |
|--------|------|------|
| `actions` | - | 操作按鈕區域 |
---
### 通用類型定義
#### TableColumn
```typescript
interface TableColumn<T = Record<string, unknown>> {
prop?: keyof T | string
label: string
width?: number | string
type?: 'selection' | 'index' | 'expand'
fixed?: boolean | 'left' | 'right'
align?: 'center' | 'left' | 'right'
sortable?: boolean | 'custom'
formatter?: (row: T) => string
template?: (row: T) => VNode
minWidth?: number | string
headerAlign?: 'center' | 'left' | 'right'
checkActive?: boolean
}
```
#### SortChangValue
```typescript
interface SortChangValue<T = any> {
column: TableColumn<T>
prop: keyof T | string
order: 'ascending' | 'descending' | null
}
```
#### SortInfo
```typescript
interface SortInfo<T = any> {
column: TableColumn<T>
prop: keyof T | string
order: 'ascending' | 'descending' | null
}
```
#### Pager
```typescript
interface Pager {
page: number
limit: number
totalCount: number
}
```
## 🎨 樣式系統
### 樣式導入方式
本組件庫提供多種靈活的樣式導入方式,您可以根據項目需求選擇:
#### 1. 完整樣式導入(推薦)
適用於大多數項目,一次性導入所有樣式:
```typescript
// main.ts
import 'element-plus/dist/index.css'
import 'rayyy-vue-table-components/styles'
```
或在 CSS/SCSS 文件中:
```scss
// styles.scss
@import 'element-plus/dist/index.css';
@import 'rayyy-vue-table-components/styles';
```
#### 2. 模組化導入
按需導入特定模組的樣式:
```scss
// 只導入表格相關樣式
@import 'rayyy-vue-table-components/styles/table';
// 只導入對話框相關樣式
@import 'rayyy-vue-table-components/styles/dialog';
// 只導入組件樣式
@import 'rayyy-vue-table-components/styles/components';
```
#### 3. Element Plus 主題自定義
如果您需要自定義 Element Plus 主題:
```scss
// styles.scss
@import 'element-plus/dist/index.css';
@import 'rayyy-vue-table-components/styles/element';
```
### 樣式類別
組件庫提供預定義的 CSS 類別,您可以直接在組件中使用:
```vue
<template>
<!-- 使用預定義的樣式類別 -->
<div class="filter-btn">篩選按鈕</div>
<div class="transfer-active-bg">轉移項目</div>
<div class="table-cell">表格單元格</div>
</template>
```
### 自定義主題
您可以通過 CSS 變量來自定義組件主題:
```scss
:root {
// 主色調
--primary-color: #409eff;
--primary-light: #ecf5ff;
// 文字顏色
--text-primary: #303133;
--text-regular: #606266;
--text-secondary: #909399;
// 邊框顏色
--border-color: #dcdfe6;
--border-light: #e4e7ed;
// 背景顏色
--bg-color: #ffffff;
--bg-light: #f5f7fa;
}
```
### Tailwind CSS 集成
如果您的項目使用 Tailwind CSS,可以直接使用工具類:
```vue
<template>
<BaseTable
:data="tableData"
:columns="columns"
class="shadow-lg rounded-lg"
:base-table-row-class-name="getRowClass"
/>
</template>
<script setup lang="ts">
const getRowClass = ({ row, rowIndex }: any) => {
return [
'hover:bg-gray-50',
'transition-colors',
rowIndex % 2 === 0 ? 'bg-white' : 'bg-gray-25'
].join(' ')
}
</script>
```
### 響應式設計
組件內建響應式支援,您也可以使用響應式工具類:
```vue
<template>
<BaseTable
:data="tableData"
:columns="columns"
class="w-full sm:w-auto lg:w-full"
/>
</template>
```
## 🛠️ 開發指南
### 環境要求
- Node.js 22.0+
- npm 10.0+
- Vue 3.5+
- Element Plus 2.11+
- TypeScript 5.8+
### 本地開發
```bash
# 克隆項目
git clone https://github.com/your-username/vue-table-components.git
cd vue-table-components
# 安裝依賴
npm install
# 開發模式(啟動演示網站)
npm run dev
# 構建組件庫
npm run build-lib
# 構建演示網站
npm run build-demo
# 運行單元測試
npm run test:unit
# 運行 E2E 測試
npm run test:e2e
# 代碼檢查和格式化
npm run lint
npm run format
# TypeScript 類型檢查
npm run type-check
```
### 快速發布
使用內建的發布腳本快速發布新版本:
```bash
# 修復版本 (1.3.10 -> 1.3.11)
npm run release:patch
# 次要版本 (1.3.10 -> 1.4.0)
npm run release:minor
# 主要版本 (1.3.10 -> 2.0.0)
npm run release:major
```
發布腳本會自動執行:
- ✅ 運行所有測試
- ✅ 代碼品質檢查
- ✅ TypeScript 類型檢查
- ✅ 構建組件庫
- ✅ 更新版本號
- ✅ 創建 git tag
- ✅ 推送到遠端
- ✅ 發布到 npm
### 項目結構
```
src/
├── components/ # 組件源碼
│ ├── form/ # 表單組件
│ │ └── BaseInput.vue
│ ├── items/ # 交互組件
│ │ ├── BaseBtn.vue
│ │ ├── BaseDialog.vue
│ │ ├── BaseWaringDialog.vue
│ │ └── SearchBar.vue
│ ├── tables/ # 表格組件
│ │ ├── BaseTable.vue
│ │ ├── SortTable.vue
│ │ └── TitleTable.vue
│ ├── layout/ # 佈局組件
│ │ ├── MainPanel.vue
│ │ ├── DetailLayout.vue
│ │ ├── FilterLayout.vue
│ │ ├── FunctionHeader.vue
│ │ └── SearchableListPanel.vue
│ ├── transfer/ # 轉移組件
│ │ ├── TransferDialog.vue
│ │ └── transferItem.vue
│ └── index.ts # 組件導出
├── assets/styles/ # 樣式文件
│ ├── tailwind.scss # 主樣式入口
│ ├── _base.scss # 基礎樣式
│ ├── _tables.scss # 表格相關樣式
│ ├── _dialogs.scss # 對話框相關樣式
│ ├── _components.scss # 組件樣式
│ └── element/ # Element Plus 主題
├── types/ # 類型定義
│ ├── components.d.ts # 組件類型定義
│ └── index.ts # 類型導出
├── utils/ # 工具函數
│ ├── tableHelper.ts # 表格工具函數
│ └── routeFormatters.ts # 路由格式化
├── views/ # 演示頁面
│ ├── demo/ # 組件演示
│ └── DemoPage.vue # 演示首頁
├── router/ # 路由配置
├── const/ # 常量定義
└── index.ts # 主入口文件
```
### 貢獻指南
歡迎貢獻代碼!請遵循以下步驟:
1. Fork 本項目
2. 創建功能分支:`git checkout -b feature/amazing-feature`
3. 提交更改:`git commit -m 'Add some amazing feature'`
4. 推送分支:`git push origin feature/amazing-feature`
5. 提交 Pull Request
## 🤝 社區與支持
### 問題反饋
如果您遇到問題或有功能建議,請通過以下方式聯繫我們:
- [GitHub Issues](https://github.com/your-username/vue-table-components/issues)
- [討論區](https://github.com/your-username/vue-table-components/discussions)
### 版本更新
查看 [CHANGELOG.md](./CHANGELOG.md) 了解詳細的版本更新記錄。
#### 最新更新 (v2.0.22)
**🌐 國際化 (i18n) 支持**
- ✅ 新增完整的國際化支持,支援繁體中文 (zh-TW) 和英文 (en-US)
- ✅ 所有組件文字已替換為 i18n 翻譯鍵值
- ✅ 支援外部專案語系同步,需要合併 JSON 檔案使用
- ✅ 提供 `vue-i18n` 整合,支援 `>=10.0.0` 版本
- ✅ 新增語系切換功能,支援動態語言切換
- ✅ 提供翻譯檔案自動更新腳本,支援 Google Sheets 整合
- ✅ **SearchableListPanel 支援 locale prop 來覆寫 i18n 設定**
**🔧 技術改進**
- ✅ 修復 `vue-i18n` 依賴版本衝突問題
- ✅ 優化模組導出配置,支援 `./locales` 子路徑導入
- ✅ 完善 TypeScript 類型定義,提供完整的 i18n 類型支持
- ✅ 修復構建配置,確保翻譯檔案正確打包
- ✅ 更新 Vite 配置,優化 i18n 資源處理
**📦 新增功能**
- ✅ 新增 `useI18n` 和 `setLocale` 工具函數
- ✅ 新增 `messages` 和 `LocaleType` 類型導出
- ✅ 新增 i18n 測試演示頁面
- ✅ 新增語系切換按鈕和演示功能
### 組件統計
本組件庫目前包含 **15 個組件**,涵蓋以下類別:
| 類別 | 組件數量 | 主要組件 |
|------|----------|----------|
| 🗂️ 表格組件 | 3 | BaseTable, SortTable, TitleTable |
| 🎛️ 表單組件 | 1 | BaseInput |
| 🎨 交互組件 | 3 | BaseBtn, BaseDialog, BaseWaringDialog, SearchBar |
| 🏗️ 佈局組件 | 5 | MainPanel, DetailLayout, FilterLayout, FunctionHeader, SearchableListPanel |
| 🔄 轉移組件 | 2 | TransferDialog, TransferItem |
### 相關鏈接
- [Vue 3 官方文檔](https://vuejs.org/)
- [Element Plus 官方文檔](https://element-plus.org/)
- [TypeScript 官方文檔](https://www.typescriptlang.org/)
- [Tailwind CSS 官方文檔](https://tailwindcss.com/)
- [Vite 官方文檔](https://vitejs.dev/)
- [Vitest 測試框架](https://vitest.dev/)
## 📄 許可證
本項目基於 [MIT License](./LICENSE) 開源協議。
---
<p align="center">
Made with ❤️ by the Vue Table Components Team
</p>