一、 核心組成與基本結構
Element UI 的表格主要由以下幾個核心部分構成:
<el-table>
: 表格的根容器,負責管理數據、選擇、排序、分頁集成等全局狀態。<el-table-column>
: 定義表格的一列。表格的列結構由一個或多個?<el-table-column>
?組件定義。data
: 傳遞給?<el-table>
?的?data
?屬性,是一個數組,數組中的每個對象代表表格中的一行數據。prop
:?<el-table-column>
?的?prop
?屬性,指定該列顯示?data
?數組中每個對象的哪個屬性的值。label
:?<el-table-column>
?的?label
?屬性,定義該列的標題。
最基礎的示例:
<template><el-table :data="tableData" style="width: 100%"><el-table-column prop="date" label="日期" width="180"></el-table-column><el-table-column prop="name" label="姓名" width="180"></el-table-column><el-table-column prop="address" label="地址"></el-table-column></el-table>
</template><script>
export default {data() {return {tableData: [{date: '2016-05-02',name: '王小虎',address: '上海市普陀區金沙江路 1518 弄'}, {date: '2016-05-04',name: '王小虎',address: '上海市普陀區金沙江路 1517 弄'}]}}
}
</script>
二、?<el-table>
?詳解 (根容器)
管理表格的整體行為和外觀。
- 關鍵屬性:
data
:?必填。綁定表格的數據源數組。height
?/?max-height
: 設置表格的高度。設置?height
?時,表格會固定高度,超出部分出現縱向滾動條。設置?max-height
?時,表格高度隨內容變化,但不超過最大值。stripe
: 是否顯示斑馬紋(隔行變色)。border
: 是否顯示縱向邊框。fit
: 列的寬度是否自撐開。true
?時,列寬會根據內容自動調整(可能不精確)。show-header
: 是否顯示表頭。highlight-current-row
: 是否要高亮當前鼠標懸停的行。current-row-key
: 高亮某一行的?key
,需要設置?row-key
。row-key
: 為數據行指定?key
,在使用?reserve-selection
,?expand
,?tree
?等功能時非常重要,推薦始終設置。通常指向數據中唯一的字段(如?id
)。empty-text
: 數據為空時顯示的文本。default-expand-all
: 默認是否展開所有行(用于樹形數據或展開行)。tooltip-effect
:?hover
?時?el-tooltip
?的效果。dark
?/?light
。row-style
: 行的 CSS 樣式,可以是對象或返回對象的函數。cell-style
: 單元格的 CSS 樣式,可以是對象或返回對象的函數。header-row-style
?/?header-cell-style
: 表頭行/單元格的樣式。row-class-name
?/?cell-class-name
: 為行/單元格添加自定義 class,可以是字符串或返回字符串的函數。
- 關鍵事件:
@select
: 當用戶手動勾選數據行的 Checkbox 時觸發。@select-all
: 當用戶手動勾選全選 Checkbox 時觸發。@selection-change
: 當選擇項發生變化時觸發。@cell-mouse-enter
?/?@cell-mouse-leave
: 單元格 hover 事件。@cell-click
?/?@cell-dblclick
: 單元格點擊/雙擊事件。@row-click
?/?@row-dblclick
: 行點擊/雙擊事件。@row-contextmenu
: 行右鍵菜單事件。@header-click
?/?@header-contextmenu
: 表頭點擊/右鍵菜單事件。@sort-change
: 當表格的排序條件發生變化時觸發。@filter-change
: 當表格的篩選條件發生變化時觸發。@current-change
: 當高亮行發生變化時觸發。@expand-change
: 當行展開狀態發生變化時觸發。
三、?<el-table-column>
?詳解 (列定義)
定義表格的每一列,是表格功能的核心。
- 關鍵屬性:
type
: 定義列的類型。這是最重要的屬性之一。selection
: 渲染一個?Checkbox
,用于多選。通常放在第一列。index
: 渲染一個索引列,顯示行的序號(從 1 開始)。expand
: 渲染一個可展開的按鈕(+/-),用于展開行顯示額外內容。
prop
: 指定該列顯示數據對象中的哪個屬性的值。例如?prop="name"
?會顯示?row.name
。label
: 該列的標題。width
: 設置該列的寬度(像素值,如?180
)。min-width
: 設置該列的最小寬度。當?fit=true
?時,列寬會自適應,但不會小于?min-width
。fixed
: 列是否固定。true
?/?left
?/?right
。固定列在表格橫向滾動時會固定在左側或右側。sortable
: 該列是否可排序。true
?/?custom
。custom
?時需要監聽?@sort-change
?事件自行處理排序邏輯(常用于服務端排序)。sort-method
: 自定義排序方法的函數。sort-by
: 數組或字符串,指定排序時依據的屬性或計算函數。resizable
: 對應列是否可以通過拖動改變寬度。true
?/?false
。column-key
: 給列設置一個 key,用于?@filter-change
?事件的回調參數。align
: 列內容的對齊方式。left
?/?center
?/?right
。header-align
: 表頭的對齊方式。left
?/?center
?/?right
。若不設置,則繼承?align
?的值。show-overflow-tooltip
: 當內容過長被隱藏時是否顯示 tooltip。formatter
: 用來格式化顯示文本的函數。function(row, column, cellValue, index)
。filters
: 數據過濾的選項。數組格式,如?[{ text: '2016-05-01', value: '2016-05-01' }]
。filter-placement
: 過濾彈出框的定位。top-start
?/?top-end
?/?bottom-start
?等。filter-multiple
: 數據過濾的選項是否多選。filter-method
: 數據過濾使用的方法。function(value, row, column)
,返回?true
?表示顯示,false
?表示隱藏。filtered-value
: 設置的篩選條件,需要配合?filter-method
?使用。
- 插槽 (Slots):
- 默認插槽:?用于自定義列的內容。這是實現復雜列(如操作按鈕、狀態標簽、自定義組件)的最主要方式。插槽作用域 (
slot-scope
) 提供了?row
?(當前行數據),?column
?(當前列對象),?$index
?(行索引)。 header
: 用于自定義表頭的內容。
- 默認插槽:?用于自定義列的內容。這是實現復雜列(如操作按鈕、狀態標簽、自定義組件)的最主要方式。插槽作用域 (
四、 常用功能詳解
1. 多選 (Selection)
<el-table:data="tableData"@selection-change="handleSelectionChange"ref="multipleTable"
><!-- selection 列 --><el-table-column type="selection" width="55"></el-table-column><el-table-column prop="name" label="姓名"></el-table-column><!-- ... -->
</el-table><script>
export default {methods: {handleSelectionChange(val) {this.multipleSelection = val; // val 是選中行的數據對象數組},toggleSelection(rows) {// 手動切換某行的選中狀態if (rows) {rows.forEach(row => {this.$refs.multipleTable.toggleRowSelection(row);});} else {this.$refs.multipleTable.clearSelection();}}}
}
</script>
2. 排序 (Sorting)
<!-- 簡單前端排序 -->
<el-table-column prop="date" label="日期" sortable width="180"></el-table-column><!-- 自定義排序 (服務端排序) -->
<el-table-columnprop="name"label="姓名"sortable="custom"@sort-change="handleSortChange"
></el-table-column><script>
export default {methods: {handleSortChange({ column, prop, order }) {// 根據 prop 和 order ('ascending', 'descending', null) 請求服務端數據console.log(`排序字段: ${prop}, 順序: ${order}`);// fetchSortedData(prop, order);}}
}
</script>
3. 篩選 (Filtering)
<el-table-columnprop="tag"label="標簽":filters="[{ text: '家', value: '家' }, { text: '公司', value: '公司' }]":filter-method="filterTag"filter-placement="bottom-end"
><template slot-scope="scope"><!-- 使用 el-tag 展示標簽 --><el-tag :type="scope.row.tag === '家' ? 'primary' : 'success'" closeable>{{ scope.row.tag }}</el-tag></template>
</el-table-column><script>
export default {methods: {filterTag(value, row) {return row.tag === value;}}
}
</script>
4. 自定義列內容 (使用插槽)
這是最強大的功能,可以實現幾乎任何復雜的單元格內容。
<el-table-column label="操作" width="180" fixed="right"><template slot-scope="scope"><el-button @click="handleEdit(scope.$index, scope.row)" size="mini">編輯</el-button><el-button @click="handleDelete(scope.$index, scope.row)" size="mini" type="danger">刪除</el-button><!-- 條件渲染 --><el-button v-if="scope.row.status === 0" size="mini" @click="handleEnable(scope.row)">啟用</el-button><el-button v-else size="mini" @click="handleDisable(scope.row)">禁用</el-button><!-- 使用 switch --><el-switchv-model="scope.row.enabled"active-color="#13ce66"inactive-color="#ff4949"@change="handleSwitchChange(scope.row)"></el-switch></template>
</el-table-column>
5. 展開行 (Expand)
<el-table:data="tableData"style="width: 100%":row-key="getRowKey" <!-- 重要:用于展開行 -->
><!-- expand 列 --><el-table-column type="expand" width="50"><template slot-scope="props"><p>詳細信息: {{ props.row.detail }}</p><p>描述: {{ props.row.description }}</p><!-- 可以嵌套另一個表格 --><!-- <el-table :data="props.row.subData">...</el-table> --></template></el-table-column><el-table-column label="姓名" prop="name"></el-table-column><!-- ... -->
</el-table><script>
export default {methods: {getRowKey(row) {return row.id; // 返回唯一標識}}
}
</script>
6. 樹形數據與懶加載
<el-table:data="tableData"style="width: 100%;margin-bottom: 20px;"row-key="id"borderdefault-expand-all:tree-props="{children: 'children', hasChildren: 'hasChildren'}"
><el-table-column prop="name" label="名稱" sortable></el-table-column><el-table-column prop="date" label="日期" sortable></el-table-column><el-table-column prop="address" label="地址"></el-table-column>
</el-table><!-- 懶加載 -->
<el-table:data="tableData"style="width: 100%"row-key="id"border:tree-props="{children: 'children', hasChildren: 'hasChildren'}":load="load"
><!-- ... -->
</el-table><script>
export default {methods: {load(tree, treeNode, resolve) {// 模擬異步加載setTimeout(() => {resolve([{ id: 31, name: '葉子', date: '2016-05-01', address: '上海市' },{ id: 32, name: '葉子2', date: '2016-05-01', address: '上海市' }]);}, 1000);}}
}
</script>
7. 跨行/跨列合并 (Span Method)
<el-table:data="tableData":span-method="arraySpanMethod"borderstyle="width: 100%"
><!-- ... -->
</el-table><script>
export default {methods: {arraySpanMethod({ row, column, rowIndex, columnIndex }) {// 合并第一列(姓名)中相同值的行if (columnIndex === 0) {if (rowIndex % 2 === 0) {return {rowspan: 2, // 跨兩行colspan: 1 // 跨一列};} else {return {rowspan: 0, // 不顯示colspan: 0};}}}}
}
</script>
五、 高級技巧與最佳實踐
- 性能優化:
row-key
:?必須設置,尤其在數據量大或使用?reserve-selection
,?expand
?時,能極大提升性能。height
?/?max-height
: 設置固定高度,避免表格過長導致頁面卡頓。- 虛擬滾動: Element UI 原生不支持,但社區有第三方庫(如?
vue-virtual-scroll-list
)可以集成實現超大數據量的流暢滾動。
- 分頁集成:?通常?
<el-table>
?與?<el-pagination>
?組件配合使用。<el-table>
?顯示當前頁數據,<el-pagination>
?控制頁碼,通過監聽分頁變化請求新數據。 - 自定義樣式:?使用?
row-style
,?cell-style
,?row-class-name
,?cell-class-name
?或 CSS 覆蓋(注意類名)來自定義表格樣式。 - 空狀態:?使用?
empty-text
?或?slot="empty"
?插槽自定義空數據時的展示內容(如圖片、提示語)。 - 可訪問性:?確保表頭清晰,使用?
aria-*
?屬性(如果框架支持)。 - 響應式:?表格在小屏幕上可能需要橫向滾動。考慮使用?
min-width
?和?max-width
?控制列寬,或在移動端使用其他布局(如卡片列表)。
總結
Element UI 的 <el-table>
組件功能極其豐富,從基礎的數據展示到復雜的多選、排序、篩選、展開、樹形結構、合并單元格等,幾乎涵蓋了后臺管理系統的所有表格需求。掌握 <el-table-column>
的 type
, prop
, label
, slot
以及 <el-table>
的 data
, row-key
是使用它的基礎。靈活運用插槽 (slot-scope
) 是實現復雜交互和自定義內容的關鍵。結合分頁組件,可以構建出功能強大、用戶體驗良好的數據表格界面。