7.4Element Plus 分页与表格组件

发布于:2025-09-04 ⋅ 阅读:(25) ⋅ 点赞:(0)

 el-pagination el-table 

这两个组件是后台管理系统中最常用的数据展示与交互组合,通常配合使用实现 分页加载、排序、筛选、操作 等功能。


一、分页组件 el-pagination

用于控制大量数据的分页展示。

✅ 基本结构
<el-pagination
  v-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 列类型:selectionindexexpand
label string 列标题
prop string 对应字段名
width / min-width string/number 列宽
fixed string/boolean 固定列:leftright
sortable boolean/string 是否可排序,custom 为自定义
formatter Function 格式化内容函数
show-overflow-tooltip boolean 内容过长显示 tooltip
align / header-align string 对齐方式:leftcenterright

🧩 高级功能
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-column
  prop="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 = true
  setTimeout(() => {
    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.value
    const end = start + pageSize.value
    tableData.value = filtered.slice(start, end)
    total.value = filtered.length
    loading.value = false
  }, 500)
}

// 事件
const handleSearch = () => {
  currentPage.value = 1
  fetchData()
}

const handleSortChange = ({ prop, order }) => {
  sortState.prop = prop
  sortState.order = order
  currentPage.value = 1
  fetchData()
}

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-pagination
      v-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>


网站公告

今日签到

点亮在社区的每一天
去签到