vue3+element-plus+ts elplus table 实现表格动态列 表格列显示与隐藏的动态控制 支持传递插槽与多级表头

news2024/11/28 8:27:54

如题

先上效果

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

部分代码展示

Home页面

使用时除了名字不同其他没啥不同,但是我这个封装的函数或者属性较少,如果需要请自行增加

<script setup lang="ts">
import { IPage } from '@/mixins/pagination'
import { TableKey } from '@/types/enum'
import { useRouter } from 'vue-router'

const router = useRouter()

// #region ts接口

interface ITableRow {
  name: string,
  age: number,
  random: number
}

// #endregion ts接口

onMounted(() => {
  getList()
})

// #region 跳转

const toTable = () => {
  router.push({
    name: 'Table'
  })
}

// #endregion 跳转

// #region 表格

// 分页数据, 本例由于动态表格封装所以弄了一个
const pagination = ref<IPage>({
  currentPage: 1,
  pageSize: 10,
  total: 0
})

const tableData = ref<ITableRow[]>([])

// 获取列表
const getList = () => {
  const list: ITableRow[] = []
  for (let i = 0; i < 5; i++) {
    list.push({
      name: '姓名' + Math.floor(Math.random() * 10),
      age: Math.floor(Math.random() * 100),
      random: Math.random()
    })
  }
  tableData.value = list
}

// #endregion 表格


</script>

<template>
  <div class="home">
    <h1>home页面</h1>
    <div class="home-buttons">
      <div class="home-buttons-opra">
        <el-button type="primary" @click="toTable" >跳转到表格页</el-button>
      </div>
      <div class="home-buttons-tools">
        <ColumnControl :column-key="TableKey.HOME" />
      </div>
    </div>
    <div class="home-list">
      <ProjectTable :pagination="pagination" :data="tableData" :column-key="TableKey.HOME">
        <ProjectColumn label="">
          <ProjectColumn prop="name" label="姓名" />
          <ProjectColumn prop="age" label="年龄" >
            <template #default="{ row }">
              <div>
                {{ row.age }}
              </div>
            </template>
          </ProjectColumn>
        </ProjectColumn>
        <ProjectColumn prop="random" label="随机数">
          <template #default="{ row }">
            <div>
              {{ row.random }}
            </div>
          </template>
        </ProjectColumn>
      </ProjectTable>
    </div>
  </div>
</template>

<style lang="scss" scoped>
.home {
  width: 700px;
  display: flex;
  flex-direction: column;

  &-buttons {
    margin-bottom: 12px;
    display: flex;
    justify-content: space-between;
    align-items: center;
  }
}
</style>

二次封装的表格

<script setup lang="ts">
import ProjectColumn from '@/components/ProjectColumn/index.vue'
import { IPage } from '@/mixins/pagination'
import { TableKey } from '@/types/enum'
import { IColumn, ISetColumn, ISetShowColumn } from '@/store/modules/table'
import { useColumn } from '@/use/useColumn'
import { RendererElement } from 'vue'

const store = useStore()

// #region ts接口

interface Props {
  data: any[]
  height?: string | number
  pagination?: IPage
  hiddenCheckbox?: boolean
  hiddenIndex?: boolean
  columnKey: TableKey
}

interface Emits {
  (e: 'selection-change', value: any[]): void
}

// #endregion ts接口

// #region 组件传值

const props = withDefaults(defineProps<Props>(), {
  height: '100%',
  pagination: () => ({
    currentPage: 1,
    pageSize: 10,
    total: 0
  }),
  hiddenCheckbox: false,
  hiddenIndex: false
})

const emits = defineEmits<Emits>()

// #endregion 组件传值

onMounted(() => {
  initSoltList()
})

// #region 表格

// 多选切换
const selectionChange = (list: any[]) => {
  emits('selection-change', list)
}

// #endregion 表格

// #region 插槽

const slots = useSlots()
// 当前显示的插槽
const { showColumn } = useColumn(props.columnKey)

// 渲染时的插槽列表
const slotList = ref<RendererElement[]>([])

// 递归时保存全部的动态列
const tempAllColumn = ref<IColumn[]>([])
// 递归时顺便设置展示列
const tempShowColumn = ref<string[]>([])

// 初始化
const initSoltList = () => {
  if (slots.default) {
    slotList.value = slots.default() || []
    setUnique(slotList.value)
    // 如果存在展示列, 则不需要重新赋值了
    if (showColumn.value.length > 0) {
      return
    }
    const columnData: ISetColumn = {
      key: props.columnKey,
      value: tempAllColumn.value
    }
    store.dispatch('setAllColumn', columnData)
    const showColumnData: ISetShowColumn = {
      key: props.columnKey,
      value: tempShowColumn.value
    }
    store.dispatch('setShowColumn', showColumnData)
  }
}

// 设置唯一键, 利用js浅拷贝 此函数执行完成会改变 tempAllColumn 并 设置展示列  tempShowColumn
const setUnique = (list: RendererElement[], prefix?: string, column?: IColumn) => {
  list.map(item => {
    // 是column组件 且 具有label属性
    // ProjectColumn 是 组件ProjectColumn
    if (
      (item.type && item.type === ProjectColumn)
      && (item.props && item.props.label)
    ) {
      let tempColumn: IColumn = {
        value: '',
        label: ''
      }
      // 如果存在前缀 表示是子级
      if (prefix && column) {
        tempColumn = {
          value: `${prefix}-${item.props.label}`,
          label: item.props.label
        }
        if (!column.children) {
          column.children = []
        }
        column.children.push(tempColumn)
      } else { // 不存在前缀 表示不是子级
        tempColumn = {
          value: item.props.label,
          label: item.props.label
        }
        tempAllColumn.value.push(tempColumn)
      }
      tempShowColumn.value.push(tempColumn.value) // 设置展示列
      if (item.children && item.children.default) { // 存在子级
        const tempChildrenList = item.children.default({ row: {}, column: {}, $index: -1 })
        // console.log('tempChildrenList', tempChildrenList)
        setUnique(tempChildrenList, tempColumn.value, tempColumn)
      }
    }
  })
}

// #endregion 插槽

</script>

<template>
  <el-table :data="data" border stripe :height="height" @selection-change="selectionChange"
    header-cell-class-name="header-cell">
    <el-table-column v-if="!hiddenCheckbox" type="selection" align="center" width="55" />
    <el-table-column v-if="!hiddenIndex" type="index" align="center" label="#" width="60">
      <template #default="{ $index }">
        <div>
          {{ $index + (pagination.currentPage - 1) * pagination.pageSize + 1 }}
        </div>
      </template>
    </el-table-column>
    <template v-for="(item, index) in slotList" :key="index">
      <component v-if="showColumn.includes(item.props?.label)" :uni-key="item.props?.label" :column-key="columnKey" :is="item"></component>
    </template>
  </el-table>
</template>

<style lang="scss" scoped></style>

其余页面不予展示了,请下载代码后自行查看

由于代码和页面较多,所以不在此文档进行展示,以下是项目地址,具体功能请下载会后自行体验

gitee代码

注意: 由于代码使用了自动导入,刚下载完代码如果不启动的话,会有报错,是因为没有引入,当项目启动后就会运行自动导入,这时就不会报错了

代码内具有部分注释,如果不清楚或者有BUG可在本章进行评论,谢谢

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/597876.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Vue3-01-Vue3 新特性及环境搭建

Vue.js是一种被广泛使用的JavaScript框架&#xff0c;用于构建用户界面和单页面应用。Vue3是其最新的主要版本&#xff0c;引入了许多新特性并做了一些改进。 一、Vue3 性能提升 1. Object.defineProperty VS Proxy Vue2 和 Vue3 在数据响应性系统的实现上采用了不同的方式&…

通则ZLT X21 CPE使用指南

目录 设备介绍应用场景案例详细配置CPE基本配置网络实现DMZ方式实现网络互通IP Passthrough方式实现网络互通 注意事项 设备介绍 ZLT X21 是一款高性能5G室内CPE&#xff0c;支持NR(SA&NSA)、TDD-LTE、FDD-LTE&#xff0c;将蜂窝网络数据转换为WIFI和有线网口数据&#xf…

【项目实战】博客系统设计与实现

一、项目概述 1.项目需求 前端&#xff1a;展示文章&#xff0c;文章分类&#xff0c;评论&#xff0c;用户登录。 后端 &#xff1a;系统管理&#xff1a;用户管理&#xff0c;菜单管理&#xff0c;角色管理。内容管理&#xff1a;文章管理&#xff0c;分类管理&#xff0c;标…

地震勘探基础(一)之地震波

地震波 纵波/P波 (Compressional Wave) &#xff1a;质点的动方向与波的传播方向一致。天然地震时&#xff0c;纵波造成地面上下颠簸震动&#xff0c;纵波先达到地表。 纵波速度与弹性参数的关系&#xff1a;纵波速度与体积模量&#xff0c;杨氏模量&#xff0c;剪切模量&…

tcpdump 抓包工具详细图文教程(下)

目录 一、tcpdump 常用参数的使用 1.1 tcpdump -i # 指定监听网络接口 1.2 tcpdump -w # 将捕获到的信息保存到文件中&#xff0c;且不分析和打印在屏幕 1.3 tcpdump -r # 从文件中读取数据 1.4 tcpdump -n # 不把 ip 转化成域名 1.5 tcpdump -t # 在每行的输出中不…

springboot自定义注解的使用++日志

1.添加切面依赖 <dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.8.9</version> </dependency> 2.自定义注解 Target(ElementType.METHOD) Retention(RetentionPolicy.RUNTI…

Java语言---PriorityQueue与堆

目录 一.堆 1.1堆的概念 1.2堆的存储方式 1.3堆的操作 1.3.1堆的创建 1.3.2代码的实现&#xff1a; 堆的插入元素 堆的删除 二、PriorityQueue 2.1概念 2.2性质 2.3PriorityQueue的创建构造 2.4PriorityQueue的操作方法 总结 &#x1f63d;个人主页&#xff1a;t…

堆的应用:Top-K问题

朋友们、伙计们&#xff0c;我们又见面了&#xff0c;本期来给大家解读一下堆的应用--Top-K问题的相关知识点&#xff0c;如果看完之后对你有一定的启发&#xff0c;那么请留下你的三连&#xff0c;祝大家心想事成&#xff01; 数据结构与算法专栏&#xff1a;数据结构与算法 个…

基于Web智慧油库三维可视化管理系统

油库是协调原油生产、原油加工、成品油供应及运输的纽带&#xff0c;是国家石油储备和供应的基地&#xff0c;它对于保障国防和促进国民经济高速发展具有相当重要的意义。 建设背景 石油作为重要的战略资源&#xff0c;关系着国家安全和人民生活。油库是石油能源供应链中的关…

俞浩“死磕”抖音,追觅科技618面临三变数

​文 | 智能相对论 作者 | 渡过 智能清洁“新秀”追觅科技来势汹汹。 创始人俞浩曾向媒体表示&#xff0c;“追觅科技……2023年做到行业技术第一&#xff0c;2024年做到行业市占率第一&#xff0c;2025年做到行业利润第一。” 具体到市场上&#xff0c;能拱火热度的电商节…

linux实践php8.2加laravel-cotane和roadrunner服务器

php8.2 composer -v 报错&#xff1a; Deprecation Notice: strlen(): Passing null to parameter #1 ($string) of type string is deprecated in phar:///usr/bin/composer/vendor/symfony/console/Descriptor/TextDescriptor.php:290 解决方法可以升级下composer&#xff1…

像写 Rust 一样写 Python!

几年前&#xff0c;开始使用Rust编程&#xff0c;它逐渐改变了我使用其他编程语言&#xff08;尤其是Python&#xff09;设计程序的方式。在我开始使用Rust之前&#xff0c;我通常以一种非常动态和类型松散的方式编写Python代码&#xff0c;没有类型提示&#xff0c;到处传递和…

2023年江西省大学生程序设计竞赛vp赛后补题

Problem - B - Codeforces 思路&#xff1a; 显然难以讨论<的情况&#xff0c;正难则反&#xff0c;我们尝试计算>的情况以为每次a&#xff0c;他的实际贡献给b的是a%m&#xff0c;x也一样&#xff0c;所以他们先取mod我们能够大于成立&#xff0c;要求a[i]sum>mod,…

常用的表格检测识别方法——表格结构识别方法 (下)

常用的表格检测识别方法——表格结构识别方法&#xff08;下&#xff09; 3.2表格结构识别方法 表格结构识别是表格区域检测之后的任务&#xff0c;其目标是识别出表格的布局结构、层次结构等&#xff0c;将表格视觉信息转换成可重建表格的结构描述信息。这些表格结构描述信息…

深度剖析数据在内存中的存储(超详细版)

&#x1f495;"痛苦难以避免&#xff0c;而磨难可以选择。"-->村上春树&#x1f495; 作者&#xff1a;Mylvzi ​​​​​​​ 文章主要内容&#xff1a;数据在内存中的存储 目录 前言&#xff1a;数据在计算机中的存储 正文&#xff1a; 1.详解数据类型 2.整…

2023-05-31 Git将已存在的项目上传到仓库

背景 正常情况下我们是在GitHub(Gitee是一样的&#xff0c;还不卡&#xff0c;因此下文将在Gitee仓库操作)创建一个代码仓库&#xff0c;然后将仓库拉到本地&#xff0c;在本地会生成一个和仓库名称一样的文件夹&#xff0c;然后在文件夹内写代码&#xff0c;最后使用git命令将…

9 概率图模型【手写笔记】

文章目录 9 概率图模型【手写笔记】9.1 背景介绍9.2 贝叶斯网络&#xff08;Bayesian Network&#xff09;——有向图网络9.3 马尔可夫网络&#xff08;Markov Network&#xff09;——无向图网络9.4 Inferce&#xff08;推断&#xff09;——求解后验9.5 更多的图的概念 9 概率…

2023年DAMA-CDGA/CDGP数据治理认证考试形式、含金量

DAMA认证为数据管理专业人士提供职业目标晋升规划&#xff0c;彰显了职业发展里程碑及发展阶梯定义&#xff0c;帮助数据管理从业人士获得企业数字化转型战略下的必备职业能力&#xff0c;促进开展工作实践应用及实际问题解决&#xff0c;形成企业所需的新数字经济下的核心职业…

表的约束.

目录 表的约束空属性默认值列描述zerofill主键自增长唯一键外键综合案例 表的约束 真正约束字段的是数据类型&#xff0c;但是数据类型约束很单一&#xff0c;需要有一些额外的约束&#xff0c;更好的保证数据的合法性&#xff0c;从业务逻辑角度保证数据的正确性。比如有一个…

一文带你了解MySQL之undo日志

目录 一、事务回滚的需求二、事务id2.1 给事务分配id的时机2.2 事务id是怎么生成的2.3 trx_id隐藏列 三、undo日志的格式3.1 INSERT操作对应的undo日志3.2 DELETE操作对应的undo日志3.3 UPDATE操作对应的undo日志3.3.1 不更新主键的情况3.3.2 更新主键的情况 四、通用链表结构五…