给el-table实现列显隐

news2024/11/17 15:58:34

用过若依的都知道,在使用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, _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");
            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 整个文件重新注册一下,这里有操作

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

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

相关文章

周报230722

周报230722 日期范围&#xff1a;2023-07-19——2023-07-22 学习内容 学习内容/任务进度具体内容评测分班已完成完成评测笔测试题、机测试题&#xff0c;分班搭建博客已完成使用阿里云服务器&#xff0c;利用宝塔搭建halo。搭建博客教程上传博客已完成每日上传当天所学知识相…

(嵌套虚拟机)ovs+floodlight搭建sdn——模拟并检测ddos攻击

参考博文-CSDN-九瓜&#xff08;作者&#xff09;-使用OpenvSwitch KVM搭建SDN网络、完整流程 ovs安装&#xff0c;需对应版本&#xff0c;使用uname -a查看内和版本&#xff0c;官网连接http://www.openvswitch.org//download/ 如果觉得2.17.7就可以&#xff1a;那么使用命…

mybatis日志工厂

前言&#xff1a; 如果一个数据库操作&#xff0c;出现异常&#xff0c;我们需要排错&#xff0c;日志就是最好的助手 官方给我们提供了logImpl&#xff1a;指定 MyBatis 所用日志的具体实现&#xff0c;未指定时将自动查找。 默认工厂&#xff1a; 在配置文件里添加&#xf…

vue中使用vab-magnifier实现放大镜效果

效果图如下&#xff1a; 1. 首先&#xff0c;使用npm或yarn安装vab-magnifier插件&#xff1a; npm install vab-magnifier或 yarn add vab-magnifier2. 在Vue组件中引入vab-magnifier插件&#xff1a; import VabMagnifier from vab-magnifier; import vab-magnifier/lib…

边缘计算在交通行业的应用有哪些?

随着我国城市化进程的不断加快。人民生活水平不断提高。随之带来的私家车辆增多导致的交通拥堵问题。智慧交通作为一种新兴的交通模式&#xff0c;对传统交通行业产生了深远的影响。 智慧交通利用边缘计算和物联网等先进人工智能技术&#xff0c;赋能传统交通行业数字化升级。…

【JavaEE初阶】Tomcat安装与使用及初识Servlet

文章目录 1. Tomcat的安装与使用1.1 Tomcat安装1.2 Tomcat的启动1.3 Tomcat部署前端页面 2. Servlet2.1 Servlet是什么2.2 第一个Servlet程序2.3 常见错误 1. Tomcat的安装与使用 1.1 Tomcat安装 在浏览器中搜索Tomcat,打开官方网页.Tomcat官网 点击下载Tomcat8. 点击下载压…

Java语言简介

个人记录学习Java的笔记&#xff0c;内容不全面不准确 Java历史 Java是一种简单易用&#xff0c;与平台无关&#xff0c;完全面向对象的编程语言。Java诞生于20世纪90年代初期&#xff0c;前身是SUN公司为智能化家电开发的Oak语言&#xff0c;它的基础是C与C语言&#xff0c;由…

什么是iPaaS?浅谈iPaaS的未来发展方向

什么是iPaaS&#xff1f; iPaaS&#xff0c;即集成平台即服务&#xff08;Integration Platform as a Service&#xff09;&#xff0c;是一种云计算服务模型&#xff0c;旨在帮助企业简化应用程序和数据的集成过程。通过iPaaS&#xff0c;企业可以在云环境中轻松地将不同的应…

给你推荐一款快速通过 typescript 生成 jsonschema 的包处理器

theme: github fast-typescript-to-jsonschema Typescript 生成 jsonschema 数据插件 性能 案例 interface AAA {a: number;b: string;c: boolean; }解析器解析耗时fast-typescript-to-jsonschema15mstypescript-json-schema5430ms 特性 编译Typescript文件以获取完整的类…

基于因果关系知识库的因果事件图谱构建、文本预处理、因果事件抽取、事件融合等

项目设计集合&#xff08;人工智能方向&#xff09;&#xff1a;助力新人快速实战掌握技能、自主完成项目设计升级&#xff0c;提升自身的硬实力&#xff08;不仅限NLP、知识图谱、计算机视觉等领域&#xff09;&#xff1a;汇总有意义的项目设计集合&#xff0c;助力新人快速实…

postgresql四种逻辑复制的状态

准备 CreateCheckpoint&#xff0c;或者bgwriter启动时&#xff0c;或者创建logicalreplicationslot时都会调用LogStandbySnapshot 记录一个XLOG_RUNNING_XACTS类型的日志。日志中记录了所有提交的事务的xid(HistoricSnapshot) 启动&#xff08;SNAPBUILD_BUILDING_SNAPSHOT&…

uniapp使用uni-swipe-action后右侧多了小于1px的间隙

问题&#xff1a;uniapp使用uni-swipe-action后右侧多了小于1px的间隙。且在真机上没有问题&#xff0c;但是在微信开发者工具中有问题。 代码如下&#xff1a;在滑动滑块或者点击这个区域时&#xff0c;就会出现问题。 <scroll-view :scroll-y"true" :style&quo…

Android 帧率分析

卡顿&#xff1a; 界面呈现是指从应用生成帧并将其显示在屏幕上的动作。如需确保用户能够流畅地与您的应用互动&#xff0c;您的应用呈现每帧的时间不应超过 16ms&#xff0c;以达到每秒 60 帧的呈现速度&#xff08;为什么是 60fps&#xff1f;&#xff09;。如果您的应用存在…

TRT4-trt-integrate - 3 使用onnxruntime进行onnx的模型推理过程

前言&#xff1a; onnx是microsoft开发的一个中间格式&#xff0c;而onnxruntime简称ort是microsoft为onnx开发的推理引擎。允许使用onnx作为输入进行直接推理得到结果。 py接口的推理过程&#xff1a; main函数&#xff1a; if __name__ "__main__":session onn…

Faiss简单使用

Faiss是Facebook AI Research开发的快速相似性搜索&#xff08;similarity search&#xff09;计算库&#xff0c;为稠密向量提供高效相似度搜索和聚类&#xff0c;支持十亿级别向量的搜索。 Faiss 的核心原理是基于向量索引和近似最近邻搜索。它通过构建索引结构来加速相似性…

android9-android13 AMS演进初窥

目录 一&#xff1a;概览 WindowManagerService 基本介绍 ActivityManagerService 基本介绍 二&#xff1a;AMS及其关联的WMS中主要组件的类图和对像图 一&#xff1a;android 9中AMS/WMS的类图和对像图 二&#xff1a;android 10中AMS/WMS的类图和对像图 三&#xff1a…

怎么给图片去底色?这几个方法一定要知道

如果你是一位设计师或者是需要制作图片的人&#xff0c;那么你一定知道去除图片底色的重要性。无论是制作海报、广告、产品图片还是网站页面&#xff0c;去除图片底色可以让你的设计更加精细、美观、专业。在本文中&#xff0c;我们将介绍三种常见的图片去底色方法&#xff0c;…

p7付费课程笔记5:串行gc以及并行gc

前言 前段时间我们学习jvm的基础结构和gc相关的基础知识&#xff0c;今天我们详细讲讲几大gc。 串行gc 串行 GC 对年轻代使用 mark-copy (标记-复制) 算法&#xff0c;对老年代使用 mark-sweep-compact (标记-清除-整理) 算法。 两者都是单线程的垃圾收集器&#xff0c;不能…

百度AI成为移动生态强者的真相

移动互联网的发展&#xff0c;让移动生态成为了互联网企业竞争的重要战场。在这场竞争中&#xff0c;百度AI凭借着其优质的技术实力和完善的生态系统&#xff0c;成为了移动生态中的强者。 那么&#xff0c;百度AI究竟靠什么成为了强者呢&#xff1f;首先&#xff0c;百度AI的技…

网络安全/黑客零基础入门(经验分享)

相关网站推荐 博主研究方向为安全领域&#xff0c;以后可能更多的在圈子内发表文章&#xff0c;提高文章质量。 1、FreeBuf 国内关注度最高的全球互联网安全媒体平台&#xff0c;爱好者们交流与分享安全技术的社区&#xff0c;网络安全行业门户。 2、看雪 看雪论坛是个软件…