?el-pagination?el-table?
這兩個組件是后臺管理系統中最常用的數據展示與交互組合,通常配合使用實現 分頁加載、排序、篩選、操作 等功能。
一、分頁組件?el-pagination
用于控制大量數據的分頁展示。
? 基本結構
<el-paginationv-model:current-page="currentPage"v-model:page-size="pageSize":total="total":page-sizes="[10, 20, 50, 100]"layout="total, sizes, prev, pager, next, jumper"background
/>
🔧 核心屬性(Props)
屬性 | 類型 | 說明 | 默認值 |
---|---|---|---|
v-model:current-page | number | 當前頁碼(雙向綁定) | 1 |
v-model:page-size | number | 每頁條數(雙向綁定) | 10 |
total | number | 總數據條數 | 0 |
page-sizes | number[] | 每頁顯示條數選擇器選項 | [10, 20, 30, 40, 50, 100] |
layout | string | 組件布局,用逗號分隔 | 'prev, pager, next' |
background | boolean | 是否為按鈕添加背景色 | false |
disabled | boolean | 是否禁用分頁 | false |
small | boolean | 是否使用小型分頁 | false |
layout
可選值:
total
: 總條數sizes
: 每頁條數選擇器prev
: 上一頁pager
: 頁碼列表next
: 下一頁jumper
: 跳轉輸入框->
: 分隔符(將后續元素推到右側)
📢 事件(Events)
事件 | 說明 | 回調參數 |
---|---|---|
@size-change | 每頁條數改變時觸發 | 改變后的?pageSize |
@current-change | 當前頁改變時觸發 | 改變后的?currentPage |
@prev-click | 點擊上一頁時觸發 | - |
@next-click | 點擊下一頁時觸發 | - |
?? 注意:使用
v-model
后,通常只需監聽@size-change
和@current-change
來重新請求數據。
二、表格組件?el-table
用于展示結構化數據。
? 基本結構
<el-table :data="tableData" style="width: 100%"><el-table-column prop="name" label="姓名" /><el-table-column prop="age" label="年齡" />
</el-table>
🔧 表格核心屬性(el-table
?Props)
屬性 | 類型 | 說明 |
---|---|---|
data | array | 顯示的數據源 |
stripe | boolean | 是否顯示斑馬紋 |
border | boolean | 是否顯示縱向邊框 |
fit | boolean | 列寬是否自撐開 |
height | string/number | 固定高度,超出出現滾動條 |
max-height | string/number | 最大高度 |
highlight-current-row | boolean | 高亮當前行 |
empty-text | string | 數據為空時顯示文本 |
v-loading | boolean | 是否顯示加載中 |
🔧 列定義?el-table-column
?屬性
屬性 | 類型 | 說明 |
---|---|---|
type | string | 列類型:selection ,?index ,?expand |
label | string | 列標題 |
prop | string | 對應字段名 |
width ?/?min-width | string/number | 列寬 |
fixed | string/boolean | 固定列:left ,?right |
sortable | boolean/string | 是否可排序,custom ?為自定義 |
formatter | Function | 格式化內容函數 |
show-overflow-tooltip | boolean | 內容過長顯示 tooltip |
align ?/?header-align | string | 對齊方式:left ,?center ,?right |
🧩 高級功能
1. 復選框列
<el-table-column type="selection" width="55" />
2. 序號列
<el-table-column type="index" label="序號" width="80" />
3. 可展開行
<el-table-column type="expand"><template #default="props"><p>詳情:{{ props.row.detail }}</p></template>
</el-table-column>
4. 自定義列模板
<el-table-column label="操作" width="180"><template #default="{ row }"><el-button size="small" @click="edit(row)">編輯</el-button><el-button size="small" type="danger">刪除</el-button></template>
</el-table-column>
5. 排序
<el-table-column prop="age" label="年齡" sortable />
<!-- 或自定義排序 -->
<el-table-column prop="age" label="年齡" sortable="custom" @sort-change="handleSort" />
6. 篩選
<el-table-columnprop="tag"label="標簽":filters="[{ text: '家', value: '家' }, { text: '公司', value: '公司' }]":filter-method="filterTag"
/>
function filterTag(value, row) {return row.tag === value
}
三、實戰案例(完整)
<script setup>
import { ref, reactive, onMounted } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'// 響應式數據
const tableData = ref([])
const total = ref(0)
const loading = ref(false)// 分頁
const currentPage = ref(1)
const pageSize = ref(10)// 搜索與排序
const searchKey = ref('')
const sortState = reactive({ prop: '', order: '' })// 模擬數據獲取
const fetchData = () => {loading.value = truesetTimeout(() => {const allData = Array.from({ length: 100 }, (_, i) => ({id: i + 1,name: `用戶${i + 1}`,age: 18 + (i % 50),address: `地址 ${i + 1}`}))// 搜索let filtered = allData.filter(item => item.name.includes(searchKey.value))// 排序if (sortState.prop && sortState.order) {filtered.sort((a, b) => {const diff = a[sortState.prop] - b[sortState.prop]return sortState.order === 'descending' ? -diff : diff})}// 分頁const start = (currentPage.value - 1) * pageSize.valueconst end = start + pageSize.valuetableData.value = filtered.slice(start, end)total.value = filtered.lengthloading.value = false}, 500)
}// 事件
const handleSearch = () => {currentPage.value = 1fetchData()
}const handleSortChange = ({ prop, order }) => {sortState.prop = propsortState.order = ordercurrentPage.value = 1fetchData()
}const handleEdit = (row) => ElMessage.info(`編輯:${row.name}`)
const handleDelete = (row) => {ElMessageBox.confirm(`刪除 ${row.name}?`, '確認', { type: 'warning' }).then(() => ElMessage.success('刪除成功')).catch(() => ElMessage.info('取消'))
}onMounted(() => fetchData())
</script><template><div class="p-4"><div class="flex justify-between mb-4"><h3 class="text-lg font-medium">用戶列表</h3><el-input v-model="searchKey" placeholder="搜索姓名" @input="handleSearch" style="width: 240px" /></div><el-table :data="tableData" stripe border v-loading="loading" @sort-change="handleSortChange"><el-table-column type="index" label="序號" width="80" /><el-table-column prop="name" label="姓名" sortable /><el-table-column prop="age" label="年齡" sortable width="100" /><el-table-column prop="address" label="地址" show-overflow-tooltip /><el-table-column label="操作" width="160"><template #default="{ row }"><el-button size="small" @click="handleEdit(row)">編輯</el-button><el-button size="small" type="danger" @click="handleDelete(row)">刪除</el-button></template></el-table-column></el-table><el-paginationv-model:current-page="currentPage"v-model:page-size="pageSize":total="total"layout="total, sizes, prev, pager, next, jumper"background@size-change="fetchData"@current-change="fetchData"class="mt-4 justify-end"/></div>
</template>