6.2 KiB
6.2 KiB
title, date
| title | date |
|---|---|
| Element Plus 表格组件 | 2026-05-27 |
一、加载中
<el-table
v-loading="dispatchStore.isLoading"
element-loading-text="加载中..."
:data="dispatchStore.contractList"
border
stripeempty-text="暂无记录"
class="common-table">
</el-table>
::: tip
要配合pinia存储使用,获取数据前将loading置为true,完成后置为false。
:::
二、展开行
<template>
<el-table :data="dispatchStore.contractList"
:row-key="getRowKey"
:expand-row-keys="expandedRows"
@expand-change="handleExpandChange">
<el-table-column type="expand">
<template #default="props">
<el-table :data="props.row.dispatchList"
border stripeempty-text="暂无记录"
class="dispatch-content"
style="width: 100%">
<el-table-column fixed type="index" align="center" width="60" />
<el-table-column prop="customer" label="终端客户" align="center" width="180"/>
</el-table>
</template>
</el-table-column>
</el-table>
</template>
<script lang="ts" setup>
const expandedRows = ref<number[]>([])
// 获取行的唯一标识
const getRowKey = (row: IDispatch) => {
return row.id
}
// 处理展开行变化
const handleExpandChange = (row: IDispatch, expandedRowsList: IDispatch[]) => {
if (expandedRowsList.length > 0) {
// 只保留最新展开的行
expandedRows.value = [getRowKey(row)]
} else {
expandedRows.value = []
}
}
</script>
通过类型expand和插槽props实现,可以展示任意格式数据。
增加表格的row-key、expand-row-key属性可以实现只展开某一行功能。
三、排序和筛选
<template>
<el-table :data="dispatchStore.contractList">
<el-table-column prop="contractNum" label="合同编号" align="center" min-width="10%"
:filters=contractNumFilters :filter-method="filterColumnMethod" sortable>
</el-table-column>
</el-table>
</template>
<script lang="ts" setup>
import { useDispatchStore } from '@/stores/dispatch.ts'
import { computed } from 'vue'
import type { IContract } from '@/types/dispatch.ts'
const dispatchStore = useDispatchStore()
type ContractField = keyof IContract
const filterColumnMethod = (value, row, column) => {
return row[column.property] === value
}
const getFiltersByKey = (key: ContractField) => {
const result = [...new Set(dispatchStore.contractList.map((item) => item[key]).filter((value) => value != null && value !==''))]
return result.map((item) => ({
text: item,
value: item
}))
}
const contractNumFilters = computed(() => getFiltersByKey('contractNum'))
</script>
在el-table-column中添加sortable即可实现排序功能。
在el-table-column中添加filters和filter-method实现筛选功能。
filters为原始数据中该字段下的所有值,并转为指定格式,也可以自定义筛选字段。
四、表头搜索
<template>
<el-table :data="dispatchStore.contractList" >
<el-table-column prop="contractNum" label="合同编号" align="center" min-width="10%">
<template #header>
<div class="custom-header">
<span :class="{ 'active': contractNumSearch }">合同编号</span>
<el-popover ref="contractNumPopoverRef" placement="bottom" width="230" trigger="click">
<template #default>
<el-select v-model="contractNumSearch" filterable clearable
placeholder="请选择或输入合同编号" @change="applySearch('contractNum')">
<el-option v-for="(item, index) in contractNumValue"
:key="index" :label="item" :value="item"/>
</el-select>
<div style="margin-top: 8px;display: flex;justify-content: flex-end;">
<el-button type="primary" size="small" @click="applySearch('contractNum')">搜索</el-button>
<el-button size="small" @click="resetSearch('contractNum')">重置</el-button>
</div>
</template>
<template #reference>
<el-icon class="search-icon"><Search/></el-icon>
</template>
</el-popover>
</div>
</template>
</el-table-column>
</el-table>
</template>
<script lang="ts" setup>
import { useDispatchStore } from '@/stores/dispatch.ts'
import { computed, ref } from 'vue'
import { Search } from '@element-plus/icons-vue'
import type { IContract } from '@/types/dispatch.ts'
import type { PopoverInstance } from 'element-plus'
import type { Ref } from 'vue'
const dispatchStore = useDispatchStore()
type ContractField = keyof IContract
const getFiltersByKey = (key: ContractField) => {
const result = [...new Set(dispatchStore.contractList.map((item) => item[key]).filter((value) => value != null && value !== ''))]
return result.map((item) => ({
text: item,
value: item
}))
}
const contractNumFilters = computed(() => getFiltersByKey('contractNum'))
const contractNumValue = computed(() => contractNumFilters.value.map((item) => item.value))
const contractNumPopoverRef = ref<PopoverInstance>()
const contractNumSearch = ref('')
const popoverMap = new Map<string, Ref<PopoverInstance | undefined>>([
['contractNum', contractNumPopoverRef]
])
const searchMap = new Map<string, Ref<string>>([
['contractNum', contractNumSearch]
])
const applySearch = async (field: ContractField) => {
const searchRef = searchMap.get(field)
if (!searchRef) return
if (!searchRef.value) {
await dispatchStore.queryContractList()
return
}
if (!searchRef.value.trim()) return
dispatchStore.contractList = dispatchStore.contractList.filter((item) => {
const value = item[field]
return typeof value === 'string' && value.includes(searchRef.value)
})
popoverMap.get(field)?.value?.hide()
}
const resetSearch = async (field: string) => {
const searchRef = searchMap.get(field)
if (searchRef) {
searchRef.value = ''
}
popoverMap.get(field)?.value?.hide()
await dispatchStore.queryContractList()
}
</script>
表头搜索主要利用header插槽和el-popover组件实现。