当前位置: 首页 > article >正文

如何在uniapp中实现一个表格组件?

 

功能介绍:

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>


http://www.kler.cn/a/510417.html

相关文章:

  • Spring Boot项目集成Redisson 原始依赖与 Spring Boot Starter 的流程
  • 什么是SSL及SSL的工作流程
  • k8s集群安装
  • 动手学大数据-3社区开源实践
  • [创业之路-254]:《华为数字化转型之道》-1-华为是一个由客户需求牵引、高度数字化、高度智能化、由无数个闭环流程组成的价值创造、评估、分配系统。
  • 【Flink系列】6. Flink中的时间和窗口
  • SpringBoot整合ShedLock,解决定时任务防止重复执行的问题
  • 【2024年华为OD机试】 (B卷,100分)- 敏感字段加密(Java JS PythonC/C++)
  • el-date-picker根据开始时间或结束时间禁用前后时间
  • C# 数据结构全面解析
  • 自动驾驶汽车目前面临的最大技术挑战是什么?
  • linux网络编程11——线程池
  • 【MySQL】事务(二)
  • 二叉树OJ题:挑战与突破
  • springboot自动配置原理(高低版本比较)spring.factories文件的作用
  • RISC-V精简指令集
  • 雷电9最新版安装Magisk+LSPosd(新手速通)
  • 基于SSM的家庭记账本小程序设计与实现(LW+源码+讲解)
  • Git实用指南:忽略文件、命令别名、版本控制、撤销修改与标签管理
  • 国产编辑器EverEdit - 文字对齐
  • Golang学习笔记_27——单例模式
  • S4 HANA凭证更改记录
  • Xilinx FPGA :开发使用及 Tips 总结
  • K8S-Pod资源清单的编写,资源的增删改查,镜像的下载策略
  • 基于无线传感器网络的森林防火设备远程监控系统(论文+源码)
  • 根据进程id查看服务使用的垃圾收集器