功能介绍:
1 表格头自定义列。
2 表格头支持勾选功能,并且支持配置。通过配置显示或隐藏该功能
3 支持自定义样式和自定义操作。比如修改列数据内容样式,上图中年龄做了自定义的处理,点击某列内容可以自定义操作。
-------------------table 的核心代码-------------------------------
<template>
<view class="table-container">
<!-- 表格 -->
<view class="table">
<!-- 表头 -->
<view class="table-header">
<view v-if="canCheck" class="header-cell checkbox-cell">
<checkbox-group @change="handleSelectAll">
<checkbox :checked="isAllSelected" />
</checkbox-group>
</view>
<view
v-for="(column, index) in columns"
:key="index"
class="header-cell"
:style="{ width: column.width || 'auto' }"
>
{{ column.title }}
</view>
<view v-if="hasActions" class="header-cell actions-cell">操作</view>
</view>
<!-- 表格行 -->
<view class="table-body">
<view
v-for="(row, rowIndex) in data"
:key="rowIndex"
class="table-row"
:class="{ selected: selectedRows.includes(row) }"
>
<!-- 复选框 -->
<view v-if="canCheck" class="body-cell checkbox-cell">
<checkbox-group @change="(e) => handleSelectRow(row, e)">
<checkbox :checked="selectedRows.includes(row)" />
</checkbox-group>
</view>
<!-- 数据列 -->
<view
v-for="(column, colIndex) in columns"
:key="colIndex"
class="body-cell"
:style="{ width: column.width || 'auto' }"
>
<slot name="cell" :row="row" :column="column" :index="rowIndex">
<!-- 默认渲染 -->
{{ row[column.key] }}
</slot>
</view>
<!-- 操作列 -->
<view v-if="hasActions" class="body-cell actions-cell">
<slot name="actions" :row="row" :index="rowIndex"></slot>
</view>
</view>
</view>
</view>
<!-- 加载更多 -->
<view v-if="hasMore" class="load-more" @click="loadMore">
<text>点击加载更多</text>
</view>
</view>
</template>
<script setup lang="ts">
import { ref, computed, useSlots } from 'vue'
// 定义表格列接口
interface TableColumn {
title: string // 列标题
key: string // 列数据字段
width?: string // 列宽度
slot?: string
}
// 定义表格数据接口
interface TableRow {
[key: string]: any // 动态字段
}
// 定义 props
const props = defineProps<{
columns: TableColumn[] // 表格列配置
data: TableRow[] // 表格数据
canCheck?: boolean // 是否显示复选框
hasMore?: boolean // 是否还有更多数据
}>()
// 定义事件
const emit = defineEmits(['select-all', 'select-row', 'load-more'])
// 获取插槽
const slots = useSlots()
// 选中的行
const selectedRows = ref<TableRow[]>([])
// 是否全选
const isAllSelected = computed(() => {
return selectedRows.value.length === props.data.length
})
// 是否有操作列
const hasActions = computed(() => {
return !!slots.actions // 检查是否有 actions 插槽
})
// 处理全选
const handleSelectAll = (e: any) => {
if (e.detail.value.length > 0) {
selectedRows.value = [...props.data]
} else {
selectedRows.value = []
}
emit('select-all', selectedRows.value)
}
// 处理选择行
const handleSelectRow = (row: TableRow, e: any) => {
if (e.detail.value.length > 0) {
selectedRows.value.push(row)
} else {
selectedRows.value = selectedRows.value.filter((r) => r !== row)
}
emit('select-row', selectedRows.value)
}
// 加载更多
const loadMore = () => {
emit('load-more')
}
</script>
<style scoped>
.table-container {
width: 100%;
}
.table {
width: 100%;
border-collapse: collapse;
}
.table-header,
.table-row {
display: flex;
align-items: center;
border-bottom: 1px solid #eee;
}
.header-cell,
.body-cell {
padding: 10px;
text-align: left;
}
.checkbox-cell {
width: 50px;
text-align: center;
}
.actions-cell {
display: flex;
justify-content: flex-end;
}
.selected {
background-color: #f0f0f0;
}
.load-more {
text-align: center;
padding: 10px;
color: #007aff;
cursor: pointer;
}
</style>
-------------------父组件中使用-------------------------------
<Table
:columns="columns"
:data="tableData"
:canCheck="true"
:hasMore="hasMore"
@select-all="handleSelectAll"
@select-row="handleSelectRow"
@load-more="handleLoadMore"
>
<template #cell="{ row, column }">
<!-- 自定义 age 列 -->
<template v-if="column.key === 'age'">
<view @click="test" :style="{ color: '#f00' }">
{{ row.age }}
</view>
</template>
<!-- 默认渲染 -->
<template v-else>
{{ row[column.key] }}
</template>
</template>
<!-- 操作列插槽 -->
<template #actions="{ row, index }">
<button type="primary" size="mini" @click="handleDelete(row, index)">删除</button>
</template>
</Table>
<script setup>
// 表格列配置
const columns = ref([
{ title: '姓名', key: 'name', width: '40px' },
{
title: '年龄',
key: 'age',
width: '40px',
slot: 'age'
},
{ title: '地址', key: 'address' }
])
// 表格数据
const tableData = ref([
{ name: '张三', age: 25, address: '北京市' },
{ name: '李四', age: 30, address: '上海市' },
{ name: '王五', age: 28, address: '广州市' }
])
</script>