基于Vue3和Element Plus實(shí)現(xiàn)一個(gè)可定制的動(dòng)態(tài)表格列配置組件
引言
在后臺(tái)管理系統(tǒng)中,表格是最常用的數(shù)據(jù)展示方式之一。不同的用戶或不同的場(chǎng)景下,我們往往需要展示不同的表格列,或者對(duì)列的顯示方式有不同的需求。本文將介紹如何基于 Vue 3 和 Element Plus 實(shí)現(xiàn)一個(gè)可定制的動(dòng)態(tài)表格列配置組件,讓用戶可以自由選擇需要顯示的列、調(diào)整列的順序、配置列的顯示方式等。
組件設(shè)計(jì)思路
我們的動(dòng)態(tài)表格列配置組件主要由三部分組成:
- CustomizeTableColumns - 負(fù)責(zé)單個(gè)表格列的渲染
- ColumnConfigDialog - 提供列配置的交互界面
- 主頁(yè)面 - 整合組件并提供數(shù)據(jù)
這種設(shè)計(jì)遵循了單一職責(zé)原則,每個(gè)組件只關(guān)注自己的核心功能,使得代碼更加清晰、易于維護(hù)。
核心組件實(shí)現(xiàn)
1. CustomizeTableColumns 組件
<template>
<el-table-column
:prop="column.prop"
:label="column.label"
:align="column.align || 'center'"
:width="column.width"
:min-width="column.minWidth"
:fixed="column.fixed"
:sortable="column.sortable"
:formatter="column.formatter ? dateFormatter : null"
show-overflow-tooltip
>
<!-- 自定義列模板 針對(duì)特殊列通過(guò)插槽進(jìn)行特殊處理 -->
<template #default="scope" v-if="column.slot">
<slot name="column-cell" :column="column" :row="scope.row" :index="scope.$index"></slot>
</template>
</el-table-column>
</template>
<script setup lang="ts">
import { dateFormatter } from '@/utils/formatTime'
const props = defineProps({
column: {
type: Object,
required: true
}
})
</script>
功能說(shuō)明:
- 封裝了
el-table-column的基本配置 - 通過(guò)
slot支持自定義列內(nèi)容渲染 - 內(nèi)置了日期格式化功能
使用示例:
<CustomizeTableColumns v-for="col in dynamicColumns" :key="col.prop" :column="col">
<template #column-cell="{ column, row, index }">
<!-- 自定義列內(nèi)容 -->
<template v-if="column.prop === 'index'">
{{ index + (queryParams.pageNo - 1) * queryParams.pageSize + 1 }}
</template>
<template v-else-if="column.prop === 'typeName'">
<span
style="cursor: pointer; color: #409eff"
v-if="row.id"
@click="openForm('preview', row.customerName, row.customerId, row.id)"
>
{{ row.typeName }}
</span>
</template>
</template>
</CustomizeTableColumns>
2. ColumnConfigDialog 組件
<template>
<el-dialog
v-model="showDialog"
title="表格列配置"
width="800px"
append-to-body
class="column-config-dialog"
>
<!-- 對(duì)話框內(nèi)容 -->
</el-dialog>
</template>
<script setup lang="ts">
import draggable from 'vuedraggable'
const props = defineProps({
modelValue: Boolean,
columns: Array,
defaultColumns: Array
})
const emit = defineEmits(['update:modelValue', 'update:columns'])
// 控制對(duì)話框顯示
const showDialog = computed({
get: () => props.modelValue,
set: (value) => emit('update:modelValue', value)
})
// 臨時(shí)列配置
const tempColumns = ref([])
// 全選控制
const checkAll = computed({
get: () => tempColumns.value.every(col => col.visible),
set: (val) => tempColumns.value.forEach(col => col.visible = val)
})
// 保存配置
const saveColumnConfig = () => {
const newColumns = tempColumns.value.map((col, index) => ({
...col,
order: col.fixed ? col.order : index
}))
emit('update:columns', newColumns)
showDialog.value = false
}
</script>
功能特點(diǎn):
- 列可見(jiàn)性控制:可以勾選顯示/隱藏列
- 拖拽排序:使用
vuedraggable實(shí)現(xiàn)列順序調(diào)整 - 基礎(chǔ)配置:可以修改列名、對(duì)齊方式、寬度等
- 高級(jí)配置:支持固定列、最小寬度、排序等高級(jí)設(shè)置
- 全選/重置:一鍵全選或重置為默認(rèn)配置
3. 主頁(yè)面集成
<template>
<!-- 表格部分 -->
<el-table :data="list">
<CustomizeTableColumns v-for="col in dynamicColumns" :key="col.prop" :column="col">
<!-- 自定義列模板 -->
</CustomizeTableColumns>
</el-table>
<!-- 配置對(duì)話框 -->
<ColumnConfigDialog
v-model="showColumnConfig"
:columns="columnOptions"
:default-columns="defaultColumns"
@update:columns="handleColumnsUpdate"
/>
</template>
<script setup lang="ts">
// 默認(rèn)列配置
const defaultColumns = ref([])
// 當(dāng)前列配置
const columnOptions = ref([
{
prop: 'index',
label: '序號(hào)',
width: 80,
fixed: 'left',
align: 'center',
slot: true,
visible: true,
order: 0
},
{
prop: 'customerName',
label: '客戶名稱',
width: 150,
align: 'center',
visible: true,
order: 1
},
{
prop: 'typeName',
label: '任務(wù)名稱',
align: 'center',
slot: true,
visible: true,
sortable: false,
showAdvanced: true,
minWidth: 80,
order: 2
},
{
prop: 'publishUserName',
label: '發(fā)布人',
width: 150,
align: 'center',
visible: true,
sortable: false,
showAdvanced: true,
order: 3
},
{
prop: 'receiveUserName',
label: '接收人',
width: 150,
align: 'center',
visible: true,
sortable: false,
showAdvanced: false,
order: 4
},
{
prop: 'missionStatus',
label: '狀態(tài)',
width: 150,
align: 'center',
slot: true,
visible: true,
sortable: false,
showAdvanced: false,
order: 5
},
{
prop: 'missionCancelReasonName',
label: '作廢原因',
width: 150,
align: 'center',
visible: true,
sortable: false,
showAdvanced: false,
order: 6
},
{
prop: 'missionRejectReasonName',
label: '拒絕原因',
width: 150,
align: 'center',
visible: true,
sortable: false,
showAdvanced: false,
order: 7
},
{
prop: 'missionRejectReasonDesc',
label: '拒絕描述',
width: 150,
align: 'center',
visible: true,
sortable: false,
showAdvanced: false,
order: 8
},
{
prop: 'publishTime',
label: '發(fā)布時(shí)間',
minWidth: 180,
align: 'center',
sortable: false,
showAdvanced: false,
formatter: true,
visible: true,
order: 9
},
{
prop: 'operation',
label: '操作',
visible: true,
minWidth: 140,
fixed: 'right',
slot: true
}
])
// 動(dòng)態(tài)列(根據(jù)配置生成的可見(jiàn)列)
const dynamicColumns = computed(() => {
return columnOptions.value
.filter(col => col.visible)
.sort((a, b) => a.order - b.order)
})
// 處理列更新
const handleColumnsUpdate = (newColumns) => {
columnOptions.value = newColumns
}
</script>
關(guān)鍵技術(shù)點(diǎn)解析
1. 動(dòng)態(tài)列渲染原理
動(dòng)態(tài)列的核心是根據(jù)配置動(dòng)態(tài)生成 el-table-column 組件:
const dynamicColumns = computed(() => {
return columnOptions.value
.filter(col => col.visible) // 過(guò)濾出可見(jiàn)的列
.sort((a, b) => a.order - b.order) // 按順序排序
})
2. 列配置的數(shù)據(jù)結(jié)構(gòu)
每個(gè)列配置包含以下屬性:
interface ColumnConfig {
prop: string // 字段名
label: string // 顯示名稱
width?: number // 列寬
minWidth?: number // 最小寬度
align?: 'left' | 'center' | 'right' // 對(duì)齊方式
fixed?: 'left' | 'right' // 固定位置
sortable?: boolean // 是否可排序
visible: boolean // 是否顯示
order: number // 排序序號(hào)
slot?: boolean // 是否使用插槽
formatter?: boolean // 是否需要格式化
showAdvanced?: boolean // 是否顯示高級(jí)設(shè)置
}
最佳實(shí)踐建議
性能優(yōu)化:
- 對(duì)于大數(shù)據(jù)量的表格,使用虛擬滾動(dòng)
- 避免在列配置中使用復(fù)雜的計(jì)算屬性
用戶體驗(yàn):
- 提供配置導(dǎo)入/導(dǎo)出功能
- 添加配置保存成功的提示
- 考慮添加撤銷/重做功能
可訪問(wèn)性:
- 為拖拽手柄添加ARIA標(biāo)簽
- 確保對(duì)話框可以通過(guò)鍵盤操作
錯(cuò)誤處理:
- 驗(yàn)證列配置的合法性
- 提供默認(rèn)配置回退機(jī)制
效果演示


總結(jié)
本文介紹了一個(gè)基于 Vue 3 和 Element Plus 的動(dòng)態(tài)表格列配置組件的完整實(shí)現(xiàn)方案。通過(guò)將功能拆分為多個(gè)組件,我們實(shí)現(xiàn)了可維護(hù)的表格列配置的動(dòng)態(tài)表格。關(guān)鍵點(diǎn)包括:
- 使用
vuedraggable實(shí)現(xiàn)列順序拖拽調(diào)整 - 通過(guò)計(jì)算屬性實(shí)現(xiàn)動(dòng)態(tài)列過(guò)濾和排序
- 利用 Vue 的響應(yīng)式系統(tǒng)實(shí)現(xiàn)配置的雙向綁定
- 提供基礎(chǔ)和高階的列配置選項(xiàng)
這種方案可以輕松集成到各種后臺(tái)管理系統(tǒng)中,大大提升了表格的靈活性和用戶體驗(yàn)。開(kāi)發(fā)者可以根據(jù)實(shí)際需求進(jìn)一步擴(kuò)展功能,如添加列分組、條件格式化等高級(jí)特性。
以上就是基于Vue3和Element Plus實(shí)現(xiàn)一個(gè)可定制的動(dòng)態(tài)表格列配置組件的詳細(xì)內(nèi)容,更多關(guān)于Vue3 Element Plus動(dòng)態(tài)表格列組件的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
vue使用element-ui的el-input監(jiān)聽(tīng)不了回車事件的解決方法
小編在使用element-ui時(shí),el-input組件監(jiān)聽(tīng)不了回車事件,怎么回事呢?下面小編給大家?guī)?lái)了vue使用element-ui的el-input監(jiān)聽(tīng)不了回車事件的解決方法,一起看看吧2018-01-01
vue3封裝Element導(dǎo)航菜單的實(shí)例代碼
這篇文章主要介紹了vue3封裝Element導(dǎo)航菜單的實(shí)例代碼,分為菜單數(shù)據(jù)格式示例,控制導(dǎo)航收縮的詳細(xì)代碼,本文通過(guò)實(shí)例代碼介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧2024-03-03
vue2升級(jí)vue3問(wèn)題bug解決分析整理
這篇文章主要介紹了vue2升級(jí)vue3遇到的問(wèn)題bug解決分析整理,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-10-10
詳解webpack編譯多頁(yè)面vue項(xiàng)目的配置問(wèn)題
本篇文章主要介紹了詳解webpack編譯多頁(yè)面vue項(xiàng)目的配置問(wèn)題,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-12-12
vue-cli webpack 開(kāi)發(fā)環(huán)境跨域詳解
本篇文章主要介紹了vue-cli webpack 開(kāi)發(fā)環(huán)境跨域詳解,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-05-05
vue 實(shí)現(xiàn)網(wǎng)頁(yè)截圖功能詳解
這篇文章主要介紹了通過(guò)vue實(shí)現(xiàn)網(wǎng)頁(yè)截圖的功能,有興趣的童鞋可以了解一下2021-11-11
vue數(shù)據(jù)雙向綁定原理解析(get & set)
這篇文章主要為大家詳細(xì)解析了vue.js數(shù)據(jù)雙向綁定原理,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-03-03
解決vue2.0動(dòng)態(tài)綁定圖片src屬性值初始化時(shí)報(bào)錯(cuò)的問(wèn)題
下面小編就為大家分享一篇解決vue2.0動(dòng)態(tài)綁定圖片src屬性值初始化時(shí)報(bào)錯(cuò)的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-03-03

