Vue3+Element Plus 通用表格組件封裝與使用實踐
在中后臺項目開發(fā)中,表格是高頻使用的核心組件,基于 Element Plus 的el-table封裝通用表格組件,能夠統(tǒng)一表格樣式、簡化重復(fù)代碼、提升開發(fā)效率。本文將詳細講解一款通用表格組件的封裝思路、完整實現(xiàn)及使用方式,該組件兼顧了通用性與靈活性,適配日常開發(fā)中的各類表格場景。
一、封裝思路
本次封裝的核心目標是打造一款「基礎(chǔ)能力通用化、個性化配置靈活化」的表格組件:
- 抽離表格通用配置(如高度、高亮行、合并單元格方法)作為基礎(chǔ) Props;
- 將
el-table和el-pagination的原生屬性 / 事件通過透傳方式交給父組件控制,保留原生組件的靈活性; - 統(tǒng)一列渲染邏輯,支持自定義
render函數(shù)實現(xiàn)復(fù)雜單元格內(nèi)容展示; - 整合表格標題、分頁等常用元素,形成完整的表格模塊。
二、通用表格組件完整實現(xiàn)(MineTable.vue)
<template>
<el-card class="mine-table">
<!-- 表格標題 -->
<el-text class="table-name">{{ tableName }}</el-text>
<!-- 核心表格容器 -->
<el-table
ref="elTable"
class="base-table"
:highlight-current-row="currentRow"
:preserve-expanded-content="true"
:span-method="spanMethod"
:data="data"
:height="height"
v-bind="tableProps" <!-- 透傳el-table原生屬性 -->
v-on="tableEvents" <!-- 透傳el-table原生事件 -->
>
<el-table-column
v-for="(item, index) in columnsData"
:key="index"
v-bind="item" <!-- 透傳列配置屬性 -->
>
<!-- 展開列自定義渲染 -->
<template v-if="item.type === 'expand'" #default="scope">
<component :is="item.render" v-bind="scope"></component>
</template>
</el-table-column>
</el-table>
<!-- 分頁組件 -->
<el-pagination
class="base-pagination"
layout="total, sizes, prev, pager, next, jumper"
:page-sizes="[5, 10, 20, 30, 40, 50]"
background
v-bind="paginationProps" <!-- 透傳el-pagination原生屬性 -->
v-on="paginationEvents" <!-- 透傳el-pagination原生事件 -->
/>
</el-card>
</template>
<script setup>
import { computed, ref } from "vue"
// 關(guān)閉默認屬性透傳,避免屬性泄露到外層DOM節(jié)點
defineOptions({
inheritAttrs: false
})
// 定義組件Props
const props = defineProps({
// 表格基礎(chǔ)配置
tableName: { type: String, default: "", description: "表格標題" },
currentRow: { type: Boolean, default: false, description: "是否高亮當(dāng)前行" },
height: { type: String, default: "60vh", description: "表格高度" },
data: { type: Array, default: () => [], description: "表格數(shù)據(jù)源" },
columns: { type: Array, default: () => [], description: "列配置項" },
spanMethod: { type: Function, default: () => {}, description: "單元格合并方法" },
// el-table原生屬性透傳(支持所有el-table屬性)
tableProps: { type: Object, default: () => ({}) },
// el-table原生事件透傳(支持所有el-table事件)
tableEvents: { type: Object, default: () => ({}) },
// el-pagination原生屬性透傳(支持所有el-pagination屬性)
paginationProps: { type: Object, default: () => ({}) },
// el-pagination原生事件透傳(支持所有el-pagination事件)
paginationEvents: { type: Object, default: () => ({}) },
})
// 暴露表格Ref,方便父組件調(diào)用el-table的原生方法
const elTable = ref(null)
defineExpose({ elTable })
// 列數(shù)據(jù)格式化處理,統(tǒng)一支持render函數(shù)渲染
const columnsData = computed(() => {
return props.columns.map(item => ({
formatter: (row, column, cellValue, index) => formatter(item, row, column, cellValue, index),
...item
}))
})
// 單元格內(nèi)容格式化邏輯
const formatter = (item, row, column, cellValue, index) => {
// 優(yōu)先級:行數(shù)據(jù)中的render函數(shù) > 列配置中的render函數(shù) > 默認值
if (row?.[column.property]?.render) {
return row[column.property].render(row, column, cellValue, index)
} else if (item?.render) {
return item.render(row, column, cellValue, index)
}
return row[column.property]
}
</script>
<style lang="scss" scoped>
.mine-table {
width: 100%;
display: flex;
flex-direction: column;
align-items: center;
.table-name {
font-size: 18px;
font-weight: bold;
margin-bottom: 12px;
display: flex;
align-items: center;
&::after {
content: "";
width: 5px;
height: 100%;
background-color: var(--el-color-primary);
margin-right: 12px;
}
}
.base-table {
width: 100%;
margin: 0 auto;
min-width: 0;
border: var(--el-table-border);
border-radius: 4px;
}
.base-pagination {
margin-top: 12px;
}
}
</style>
核心封裝點說明
- 屬性 / 事件透傳:通過
tableProps/tableEvents、paginationProps/paginationEvents分別透傳el-table和el-pagination的原生屬性與事件,既保留了原生組件的全部能力,又無需在組件內(nèi)重復(fù)定義中轉(zhuǎn)邏輯。 - 統(tǒng)一列渲染:封裝了
formatter函數(shù),支持兩種自定義渲染方式 —— 列配置中的render函數(shù)、行數(shù)據(jù)中的render函數(shù),滿足復(fù)雜單元格的展示需求。 - 基礎(chǔ)樣式整合:內(nèi)置了表格標題、表格容器、分頁的統(tǒng)一樣式,無需在業(yè)務(wù)頁面重復(fù)編寫樣式代碼。
- Ref 暴露:將
el-table的 Ref 暴露給父組件,方便調(diào)用clearSelection、toggleRowSelection等原生方法。
三、組件使用示例
1. 基礎(chǔ)使用(僅核心配置)
這是最常用的場景,只需配置表格數(shù)據(jù)、列配置、基礎(chǔ)樣式即可:
<template>
<div class="demo-container">
<!-- 通用表格組件使用 -->
<MineTable
height="200px"
tableName="用戶列表"
:data="tableData"
:columns="tableColumns"
/>
</div>
</template>
<script setup>
import { ref } from "vue"
import MineTable from "@/components/MineTable.vue"
import { ElMessage, ElPopconfirm, ElButton, ElText } from "element-plus"
// 表格數(shù)據(jù)源
const tableData = ref([
{ id: 1, name: "張三", email: "zhangsan@example.com" },
{ id: 2, name: "李四", email: "lisi@example.com" },
{ id: 3, name: "王五", email: "wangwu@example.com" }
])
// 列配置項
const tableColumns = ref([
{ type: "index", label: "序號", width: 80 }, // 序號列
{
label: "用戶名稱",
prop: "name",
// 自定義單元格渲染
render: (row) => <ElText type="primary">{row.name}</ElText>
},
{
label: "操作",
width: 100,
// 操作列:帶確認彈窗的刪除按鈕
render: (row) => {
const deleteUser = () => {
// 模擬刪除邏輯
tableData.value = tableData.value.filter(item => item.id !== row.id)
ElMessage.success(`已刪除用戶:${row.name}`)
}
return (
<ElPopconfirm
title="確定刪除嗎?"
onConfirm={deleteUser}
confirmButtonText="確定"
cancelButtonText="取消"
v-slots={{
reference: () => <ElButton type="danger" size="small" link>刪除</ElButton>
}}
/>
)
}
}
])
</script>
<style scoped>
.demo-container {
width: 800px;
margin: 20px auto;
}
</style>
2. 進階使用(透傳原生屬性 / 事件)
如果需要使用el-table或el-pagination的原生能力(如斑馬紋、行點擊事件、分頁回調(diào)等),可通過透傳 Props 實現(xiàn):
<template>
<div class="demo-container">
<MineTable
height="300px"
tableName="用戶列表"
:data="tableData"
:columns="tableColumns"
<!-- 透傳el-table原生屬性 -->
:table-props="{
border: true, // 顯示表格邊框
stripe: true, // 斑馬紋效果
showHeader: true // 顯示表頭
}"
<!-- 透傳el-table原生事件 -->
:table-events="{
'row-click': (row) => ElMessage.info(`點擊了${row.name}的行`), // 行點擊事件
'sort-change': (val) => console.log('排序變更:', val) // 排序變更事件
}"
<!-- 透傳el-pagination原生屬性 -->
:pagination-props="{
currentPage: 1, // 當(dāng)前頁碼
pageSize: 10, // 每頁條數(shù)
total: 100 // 總條數(shù)
}"
<!-- 透傳el-pagination原生事件 -->
:pagination-events="{
'size-change': (size) => console.log('每頁條數(shù)變更:', size), // 頁大小變更
'current-change': (page) => console.log('頁碼變更:', page) // 頁碼變更
}"
/>
</div>
</template>
四、總結(jié)
本次封裝的通用表格組件具備以下特點:
- 通用性強:整合了表格標題、分頁等常用元素,統(tǒng)一了基礎(chǔ)樣式和渲染邏輯;
- 靈活性高:通過屬性 / 事件透傳,保留了 Element Plus 原生組件的全部能力,適配各類個性化需求;
- 易用性好:使用方式簡潔,基礎(chǔ)場景只需配置數(shù)據(jù)和列,進階場景可透傳原生屬性 / 事件;
- 可擴展:在此基礎(chǔ)上可進一步擴展空狀態(tài)、加載狀態(tài)、列寬自適應(yīng)等通用能力,適配更多業(yè)務(wù)場景。
該組件能夠有效減少中后臺項目中表格相關(guān)的重復(fù)代碼,提升開發(fā)效率,同時保持了足夠的靈活性,滿足不同業(yè)務(wù)場景的個性化需求。
到此這篇關(guān)于Vue3+Element Plus 通用表格組件封裝與使用實踐的文章就介紹到這了,更多相關(guān)Vue3 Element Plus 表格封裝內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- vue3?element-plus?實現(xiàn)表格數(shù)據(jù)更改功能詳細步驟
- Vue3實現(xiàn)Element Plus表格的多選功能與條件操作
- 基于Vue3和Element Plus實現(xiàn)可擴展的表格組件
- vue3基于elementplus 簡單實現(xiàn)表格二次封裝過程
- Vue3?使用Element?Plus表格單選帶checkbox功能
- vue3+element?Plus實現(xiàn)表格前端分頁完整示例
- element-plus+Vue3實現(xiàn)表格數(shù)據(jù)動態(tài)渲染
- Vue3中的element-plus表格實現(xiàn)代碼
- vue3 + ElementPlus 封裝列表表格組件包含分頁
相關(guān)文章
vite中的glob-import批量導(dǎo)入的實現(xiàn)
本文主要介紹了vite中的glob-import批量導(dǎo)入的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-07-07
vue2和elementUI?實現(xiàn)落日余暉登錄頁和滑塊校驗功能
這篇文章主要介紹了vue2和elementUI打造落日余暉登錄頁和滑塊校驗,本文通過實例代碼給大家介紹的非常詳細,需要的朋友可以參考下2023-06-06
Vue.js在數(shù)組中插入重復(fù)數(shù)據(jù)的實現(xiàn)代碼
這篇文章主要介紹了Vue.js在數(shù)組中插入重復(fù)數(shù)據(jù)的實現(xiàn)代碼,需要的朋友可以參考下2017-11-11
vue項目中企業(yè)微信使用js-sdk時config和agentConfig配置方式詳解
這篇文章主要介紹了vue項目中企業(yè)微信使用js-sdk時config和agentConfig配置,本文通過實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-12-12

