给el-table实现列显隐

用过若依的都知道,在使用el-table 时候,实现列显隐效果是要给每个列加v-if 判断的,这种代码过于繁琐,于是翻看el-table包的代码,调试后发现内部的【插入】和【删除】两个方法可以达到我们要的效果。
在这里插入图片描述
项目不提供源码,核心代码都贴上了
代码动刀看似有点多,实则一个地方就一点块。el-table的源码,若依RightToolBar,本身组件,不过轮子造完都是有用的。
没有rightBar的项目可以自己对应数据模拟一个交互操作的方式来实现

上图可以看到基于若依的RightBar组件去实现列显隐,并且存到vuex的持久化中,(vuex+本地存储中),并且去掉了原先若依的RightBar组件弹窗方式。

项目是用tailwindcss 部分class类名自己去计算
RightBar的使用方法和修改内容
  <right-toolbar
	:showSearch.sync="showSearch"
	@queryTable="getList"
	:checkTableInfo.sync="checkTableInfo"
	@interaction="x => (hiddenColumns = x)"
	:componentName="$options.name"
	/>
<template>
  <div class="top-right-btn" :style="style">
    <el-row>
      <el-tooltip class="item" effect="dark" :content="showSearch ? '隐藏搜索' : '显示搜索'" placement="top" v-if="search">
        <el-button size="mini" circle icon="el-icon-search" @click="$emit('update:showSearch', !showSearch)" />
      </el-tooltip>

      <el-tooltip class="item" effect="dark" content="刷新" placement="top">
        <el-button size="mini" circle icon="el-icon-refresh" @click="$emit('queryTable')" />
      </el-tooltip>

      <el-tooltip v-if="checkTableInfo.length" class="item" effect="dark" content="显隐列" placement="bottom-start">
        <el-popover v-model="visible" placement="right" trigger="click">
          <el-checkbox-group v-model="checkList">
            <el-checkbox class="block" v-for="(item, index) in checkTableInfo" :disabled="item === 'selection' || item === '操作'" :key="index" :label="item" />
          </el-checkbox-group>

          <el-divider class="my-4" />

          <div>
            <el-button size="mini" type="primary" @click="submit">确定</el-button>
            <el-button v-if="componentName" size="mini" @click="cancel">取消</el-button>
          </div>

          <el-button class="ml-2.5" slot="reference" size="mini" circle icon="el-icon-menu" />
        </el-popover>
      </el-tooltip>
    </el-row>
  </div>
</template>

<script>
import { mapState, mapMutations } from 'vuex'

export default {
  name: 'RightToolbar',
  data() {
    return {
      checkList: Array.from(this.checkTableInfo),
      visible: false,
    }
  },
  props: {
    showSearch: { type: Boolean, default: true },
    search: { type: Boolean, default: true },
    gutter: { type: Number, default: 10 },
    checkTableInfo: { type: Array, default: () => [] },
    componentName: { type: String, default: '' },
  },
  mounted() {
    if (this.componentName && this.tableColumns[this.componentName]) {
      this.tableColumns[this.componentName]?.length && (this.checkList = this.tableColumns[this.componentName])
      this.$emit('interaction', this.checkList)
    }
  },
  methods: {
    ...mapMutations('tablecolumn', ['setTableCache']),
    submit() {
      this.$emit('interaction', this.checkList)
      this.visible = false
      if (!this.componentName) return
      this.setTableCache({ key: [this.componentName], value: this.checkList })
    },
    cancel() {
      this.tableColumns[this.componentName]?.length && (this.checkList = this.tableColumns[this.componentName])
    },
  },
  computed: {
    ...mapState('tablecolumn', ['tableColumns']),
    style() {
      const ret = {}
      if (this.gutter) {
        ret.marginRight = `${this.gutter / 2}px`
      }
      return ret
    },
  },
}
</script>

<style lang="scss" scoped>
::v-deep .el-transfer__button {
  border-radius: 50%;
  padding: 12px;
  display: block;
  margin-left: 0px;
}
::v-deep .el-transfer__button:first-child {
  margin-bottom: 10px;
}
</style>

主页面

给table传递props 属性checkTableInfo 属性即可 一定是包括column的所有列的label

<template>
  <div>
    <right-toolbar :showSearch.sync="showSearch" @queryTable="getList" :checkTableInfo.sync="checkTableInfo" @interaction="(x) => (hiddenColumns = x)" :componentName="$options.name" />

    <el-table ref="table" :data="table.data" v-loading="table.loading" :hiddenColumns="hiddenColumns" @selection-change="(ids) => (table.ids = ids)">
      <el-table-column align="center" type="selection" width="55" />
      <el-table-column align="center" label="类型" prop="type" />
      <el-table-column align="center" label="名称" prop="name" />
      <el-table-column align="center" label="描述信息" prop="desp" />
      <el-table-column align="center" label="值" prop="value" />
      <el-table-column align="center" label="默认值" prop="defaultValue" />
      <el-table-column align="center" label="操作" class-name="small-padding fixed-width">
        <template slot-scope="{ row, column: col }">
          <el-button size="mini" type="text" icon="el-icon-edit" @click="edit(row)">修改</el-button>
          <el-button size="mini" type="text" icon="el-icon-delete" @click="del(row)">删除</el-button>
        </template>
      </el-table-column>
    </el-table>
  </div>
</template>

<script>
//  import {} from ''
export default {
  name: "Untitled-1",
  data() {
    return {
      showSearch: true,
      table: {
        ids: [],
        table: [
          {
            type: 'FilePath',
            name: 'probeEnforcement',
            desp: '文件生成路径',
            value: '/home/qchen/',
            defaultValue: '3',
          }
        ],
        loading: false,
      },
      hiddenColumns: [],
      checkTableInfo: ['selection', '类型', '名称', '描述信息', '值', '默认值', '操作'],
    };
  },

  mounted() {},

  methods: {
    getList() {}
    edit(row) {}
    del(row) {}
  },
  //  End
};
</script>

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

将node_modules中将table的源码找到,打开里面的table.vue
将package里面的table源码导出,复制到components/ElementUI目录下即可修改代码,需要在main.js中覆盖element的el-table,最底下贴过一个链接有覆盖的路径

<script>
import { cloneDeep } from 'lodash-es'
//  watch 和props 里面加入下列两个属性
export default {
  props: {
    hiddenColumns: {
      type: Array,
      default: () => [],
    },
    // ... 其他props
  },
  watch: {
    hiddenColumns: {
      immediate: true,
      handler(value) {
        const { states } = this.store;
        const { _columns } = states;

        requestAnimationFrame(() => {
          requestAnimationFrame(() => {
            if (!this.cache_columns || !this.cache_columns.length) {
              this.cache_columns = cloneDeep(_columns);
            }

            if (!value.length) return;

            const show = this.cache_columns.filter((x) => value.includes(x.label));
            const hide = this.cache_columns.filter(x => !value.includes(x.label) && x.type !== 'selection' && x.type !== 'index')
            if (show.length) {
              const current_label = _columns.map((item) => item.label);
              const control_label = show.map((item) => item.label);

              control_label.forEach((item) => {
                if (!current_label.includes(item)) {
                  const column = show.find((x) => x.label === item);
                  this.store.commit("insertColumn", column, column.insertColumnIndex);
                }
              });
            }

            if (hide.length) {
              this.cache_columns.forEach((item) => {
                hide.forEach((ite) => {
                  if (item.label === ite.label) {
                    const column = _columns.find((x) => x.label === item.label);
                    column && this.store.commit("removeColumn", column);
                  }
                });
              });
            }
          });
        });
      },
    },
    // ... 其他监听
  },

  //  End
};
</script>
将el-table的源码找到,翻开/El-Table/store/index.js。 约30行的位置
  insertColumn(states, column, index, parent) {
    let array = states._columns
    if (parent) {
      array = parent.children
      if (!array) array = parent.children = []
    }

    if (typeof index !== 'undefined') {
      array.splice(index, 0, column)
    } else {
      array.push(column)
    }

    if (column.type === 'selection') {
      states.selectable = column.selectable
      states.reserveSelection = column.reserveSelection
    }

    if (!column.insertColumnIndex) { // 加入 index 标识,插入时用到
      column.insertColumnIndex = index
    }

    if (this.table.$ready) {
      this.updateColumns() // hack for dynamics insert column
      this.scheduleLayout()
    }
  },

最后将重新注册的el-table 整个文件重新注册一下,这里有操作

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

哈希表的简单模拟实现

文章目录 底层结构哈希冲突闭散列定义哈希节点定义哈希表**哈希表什么情况下进行扩容&#xff1f;如何扩容&#xff1f;**Insert()函数Find()函数二次探测HashFunc()仿函数Erase()函数全部的代码 开散列定义哈希节点定义哈希表Insert()函数Find()函数Erase()函数总代码 初识哈希…

《golang设计模式》第一部分·创建型模式-02-原型模式(Prototype)

文章目录 1. 概念1.1 简述1.2 角色1.3 类图 2. 代码示例2.1 设计2.2 代码2.3 类图 1. 概念 1.1 简述 用原型实例指定创建对象的种类&#xff0c;并且通过拷贝这些原型创建新的对象 1.2 角色 Prototype&#xff08;抽象原型类&#xff09;&#xff1a;它是声明克隆方法的接口…

ST官方基于米尔STM32MP135开发板培训课程(一)

本文将以Myirtech的MYD-YF13X以及STM32MP135F-DK为例&#xff0c;讲解如何使用STM32CubeMX结合Developer package实现最小系统启动。 1.开发准备 1.1 Developer package准备 a.Developer package下载&#xff1a; ‍https://www.st.com/en/embedded-software/stm32mp1dev.ht…

【Redis】如何实现一个合格的分布式锁

文章目录 参考1、概述2、Redis粗糙实现3、遗留问题3.1、误删情况3.2、原子性保证3.3、超时自动解决3.4、总结 4、Redis实现优缺5、集群问题5.1、主从集群5.2、集群脑裂 6、RedLock7、Redisson7.1、简单实现7.2、看门狗机制 参考 Redisson实现Redis分布式锁的N种姿势 (qq.com)小…

如何评判算法好坏?复杂度深度解析

如何评判算法好坏&#xff1f;复杂度深度解析 1. 算法效率1.1 如何衡量一个算法好坏1.2 算法的复杂度 2 时间复杂度2.1 时间复杂度的概念2.1.1 实例 2.2 大O的渐进表示法2.3 常见时间复杂度计算举例 3 空间复杂度4 常见复杂度对比5 结尾 1. 算法效率 1.1 如何衡量一个算法好坏 …

接口自动化测试要做什么?8个步骤讲的明明白白(小白也能看懂系列)

先了解下接口测试流程&#xff1a; 1、需求分析 2、Api文档分析与评审 3、测试计划编写 4、用例设计与评审 5、环境搭建&#xff08;工具&#xff09; 6、执行用例 7、缺陷管理 8、测试报告 那"接口自动化测试"怎么弄&#xff1f;只需要在上篇文章的基础上再梳理下就…

Web3.0实战(02)-联盟链入门讲解

联盟链是介于公有链和私有链之间&#xff0c;具备部分去中心化的特性。 联盟链是由若干机构联合发起&#xff0c;由盟友共同来维护&#xff0c;它只针对特定某个群体的成员和有限的第三方开放。 8.1 部分去中心化 联盟链只属于联盟内部的成员所有&#xff0c;联盟链的节点数…

SpringBoot整合Elasticsearch

SpringBoot整合Elasticsearch SpringBoot整合Elasticsearch有以下几种方式&#xff1a; 使用官方的Elasticsearch Java客户端进行集成 通过添加Elasticsearch Java客户端的依赖&#xff0c;可以直接在Spring Boot应用中使用原生的Elasticsearch API进行操作。参考文档 使用Sp…

为什么要学框架?什么是Spring?

为什么要学框架&#xff1f;什么是Spring&#xff1f; 一、为什么要学框架&#xff1f; 学习框架相当于从 “小作坊” 到 “工厂” 的升级&#xff0c;小作坊什么都要自己做&#xff0c;工厂是组件式装配&#xff0c;特点就是高效。框架更加易用、简单且高效。 框架的优点展…

7.26 作业 QT

1.继续完善登录框&#xff0c;当登录成功时&#xff0c;关闭登录界面&#xff0c;跳转到新的界面中&#xff1a; 结果图&#xff1a; second.h: #define SECOND_H#include <QWidget> #include<QDebug> //信息调试类&#xff0c;用于打印输出的 #inc…

【C语言初阶】指针篇—上

目录 1. 指针是什么&#xff1f;2. 指针和指针类型2.1 指针-整数2.2 指针的解引用 3. 野指针3.1 野指针成因1. 指针未初始化2. 指针越界访问3. 指针指向的空间释放 3.2 如何规避野指针 1. 指针是什么&#xff1f; 指针是什么&#xff1f; 指针理解的2个要点&#xff1a; > 1…

【Nodejs】Express模板使用

1.Express脚手架的安装 安装Express脚手架有两种方式&#xff1a; 使用express-generator安装 使用命令行进入项目目录&#xff0c;依次执行&#xff1a; cnpm i -g express-generator可通过express -h查看命令行的指令含义 express -hUsage: express [options] [dir] Optio…

spring eurake中使用IP注册

在开发spring cloud的时候遇到一个很奇葩的问题&#xff0c;就是服务向spring eureka中注册实例的时候使用的是机器名&#xff0c;然后出现localhost、xxx.xx等这样的内容&#xff0c;如下图&#xff1a; eureka.instance.perferIpAddresstrue 我不知道这朋友用的什么spring c…

【Redis】高级篇: 一篇文章讲清楚Redis的单线程和多线程

目录 面试题 Redis到底是多线程还是单线程&#xff1f; 简单回答 详解 Redis的“单线程” Redis为什么选择单线程&#xff1f; 后来Redis为什么又逐渐加入了多线程特性&#xff1f; Redis为什么快&#xff1f; 回答 IO多路复用 Unix网络编程的5种IO模型 主线程和IO…

常见面试题之常见技术场景

1. 单点登录这块怎么实现的&#xff1f; 1.1 概述 单点登录的英文名叫做&#xff1a;Single Sign On&#xff08;简称 SSO &#xff09;&#xff0c;只需要登录一次&#xff0c;就可以访问所有信任的应用系统。 在以前的时候&#xff0c;一般我们就单系统&#xff0c;所有的…

DSA之查找(1):线性表的查找

文章目录 0 知识回顾1 查找1.1 查找的概念 2 线性表的查找2.1 顺序查找2.1.1 顺序查找算法2.1.2 顺序查找的性能分析2.1.3 顺序查找的特点 2.2 折半查找&#xff08;二分&#xff09;2.2.1 折半查找算法2.2.2 折半查找的性能分析2.2.3 折半查找的特点 2.3 分块查找2.3.1 分块查…

0基础系列C++教程 从0开始 第二课

0基础系列C教程 从0开始 第二课来了&#xff01; 复习第一课内容 1 怎么输出数字“1919810”&#xff1f; 答案&#xff08;关键语句&#xff09;: cout<<"1919810"; 2 怎么输出字符串“Hello World”&#xff1f; 答案&#xff08;关键语句&#xff09;&a…

梯度提升树的基本思想

目录 1. 梯度提升树 VS AdaBoost 2. GradientBoosting回归与分类的实现 2.1 GradientBoosting回归 2.2 GradientBoosting分类 1. 梯度提升树 VS AdaBoost 梯度提升树&#xff08;Gradient Boosting Decision Tree&#xff0c;GBDT&#xff09;是提升法中的代表性算法&#…

朝花夕拾思维导图怎么画?看看这种绘制方法

朝花夕拾思维导图怎么画&#xff1f;绘制思维导图的好处有很多&#xff0c;首先它可以帮助人们更好地组织和管理知识&#xff0c;提高工作效率和学习效果。其次&#xff0c;绘制思维导图可以帮助人们更好地记忆知识点和理解知识点。总之&#xff0c;绘制思维导图可以帮助人们更…

cookie

目录 一、会话技术 二、Cookie 1.创建Cookie 2.使用response响应Cookie给客户端&#xff08;浏览器&#xff09; 3. 获取Cookie 三、Cookie的原理解析 1. 基本实现原理 &#xff08;1&#xff09;响应头&#xff1a;set—cookie &#xff08;2&#xff09;请求头&…