自定义antd或element table 列设置组件(拖拽排序及控制是否展示)

news2024/11/17 11:00:05

需求

  • 展示出所有的字段
  • 显示当前展示的是哪些字段
  • 可以全选、取消全选
  • 可以拖拽排序,更改字段的展示顺序,在前面还是在后面
  • 可以保存配置,刷新不失效

难点

  • 如何进行拖拽排序,自己手写一个吗?
  • 如何得到拖拽后的顺序?(个人觉得这个比较难)

效果

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

实现

  • 可以设计传入可以展示的全部字段数组当前展示字段的数组保存配置的名称,这样就能解决控制字段是否展示的需求。
  • 如何实现拖拽排序,不建议自己写,有现成的组件,而且能够返回排序后的顺序👍。推荐一个vue.draggable.next 中文文档简单好用。
  • 保存配置,这里是使用localStorage。注意踩坑:JSON.stringify不会保留函数,意味着你的一些排序函数,customRender函数会丢失。 页面进来加载配置时需要进行重新赋值

组件源码

<template>
  <a-tooltip>
    <template #title>{{ compTitle }}</template>
    <setting-outlined
      style="color: var(--theme-color)"
      @click="handleShowDrawer"
    />
  </a-tooltip>
  <a-drawer
    v-model:visible="drawerVisible"
    :title="compTitle"
    placement="right"
  >
    <div>
      <a-checkbox
        v-model:checked="checkAll"
        :indeterminate="indeterminate"
        @change="onCheckAllChange"
      >
        全选
      </a-checkbox>
      <span style="float: right">已选择 {{ checkedList.length }} 个 </span>
    </div>
    <a-checkbox-group
      class="checkbox-group"
      v-model:value="checkedList"
      @change="handleColumnChange"
    >
      <draggable
        v-model="allColumns"
        :item-key="(item) => item.dataIndex"
        handle=".move"
        animation="300"
        @end="onDragColumnEnd"
      >
        <template #item="{ element }">
          <li class="move">
            <drag-outlined style="font-size: 16px; margin-right: 10px" />
            <a-checkbox :value="element.dataIndex">
              {{ element.title }}</a-checkbox
            >
          </li>
        </template>
      </draggable>
    </a-checkbox-group>
    <template #footer>
      <div class="drawer-footer">
        <a-button @click="drawerVisible = false">取消</a-button>
        <a-button
          style="margin-left: 10px"
          type="primary"
          @click="handleSaveSetting"
          >保存</a-button
        >
      </div>
    </template>
  </a-drawer>
</template>

<script setup>
import { ref, watch, watchEffect } from 'vue'
import { message } from 'ant-design-vue'
import { SettingOutlined, DragOutlined } from '@ant-design/icons-vue'
import draggable from 'vuedraggable'

const props = defineProps({
  allColumnList: {
    // 所有列数组
    type: Array,
    default: () => []
  },
  currentColumns: {
    // 当前列数组
    type: Array,
    default: () => []
  },
  settingName: {
    type: String,
    default: 'column_setting'
  }
})
const emits = defineEmits(['columnChanged', 'columnOrderChanged'])
const compTitle = ref('列设置')
// 抽屉展示相关
const drawerVisible = ref(false)
const handleShowDrawer = () => {
  drawerVisible.value = true
}
// 选择列相关
const allColumns = ref([])
const checkedList = ref([])
watchEffect(() => {
  allColumns.value = props.allColumnList.filter(
    (item) => item.dataIndex !== 'action'
  )
  checkedList.value = props.currentColumns
    .filter((item) => item.dataIndex !== 'action')
    .map((item) => item.dataIndex)
})
// 监听列顺序改变
const onDragColumnEnd = () => {
  // console.log('列顺序改变', allColumns.value)
  // 新顺序的所有列
  const newOrderAllColumns = [
    ...allColumns.value,
    props.allColumnList[props.allColumnList.length - 1]
  ]
  emits('columnOrderChanged', newOrderAllColumns)
  // 生成新顺序的选中列
  const newOrderSelectColumns = [
    ...allColumns.value.filter((item) =>
      checkedList.value.includes(item.dataIndex)
    ),
    props.allColumnList[props.allColumnList.length - 1]
  ]
  emits('columnChanged', newOrderSelectColumns)
}
const checkAll = ref(false)
const indeterminate = ref(true) // 不定态
// 全选逻辑
const onCheckAllChange = (e) => {
  if (e.target.checked) {
    checkedList.value = allColumns.value.map((item) => item.dataIndex)
    handleColumnChange(checkedList.value)
  } else {
    checkedList.value = []
    handleColumnChange([])
  }
  indeterminate.value = false
}
watch(
  () => checkedList.value,
  (val) => {
    indeterminate.value = !!val.length && val.length < allColumns.value.length
    checkAll.value = val.length === allColumns.value.length
  }
)
// 处理列改变逻辑
const handleColumnChange = (dataIndexList) => {
  // console.log('新的值', dataIndexList, props.allColumnList)
  const newColumn = [
    ...props.allColumnList.filter((item) =>
      dataIndexList.includes(item.dataIndex)
    ),
    props.allColumnList[props.allColumnList.length - 1]
  ]
  emits('columnChanged', newColumn)
}
// 处理保存设置逻辑
const handleSaveSetting = () => {
  const setting = [...checkedList.value, 'action']
  const newOrderAllColumns = [
    ...allColumns.value,
    props.allColumnList[props.allColumnList.length - 1]
  ]
  localStorage.setItem(props.settingName, JSON.stringify(setting))
  localStorage.setItem(
    `${props.settingName}Order`,
    JSON.stringify(newOrderAllColumns)
  )
  message.success('保存成功')
  drawerVisible.value = false
}

defineExpose({
  SettingOutlined,
  DragOutlined,
  compTitle,
  draggable,
  drawerVisible,
  allColumns,
  checkedList,
  checkAll,
  indeterminate,
  handleShowDrawer,
  onCheckAllChange,
  handleSaveSetting,
  handleColumnChange,
  onDragColumnEnd
})
</script>

<style lang="less" scoped>
.checkbox-group {
  display: flex;
  flex-direction: column;
}
.drawer-footer {
  display: flex;
  justify-content: flex-end;
}
.move {
  list-style: none;
  cursor: move;
}
:deep(.ant-checkbox-wrapper + .ant-checkbox-wrapper) {
  margin-left: 0;
}
</style>

组件使用

在这里插入图片描述
在这里插入图片描述
懂得都懂

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

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

相关文章

verilog学习笔记- 8)状态机

目录 概念&#xff1a; 状态机的模型&#xff1a; 状态机的设计&#xff1a; 根据状态机的实际写法&#xff0c;状态机可以分为一段式、二段式和三段式状态机。 三段式状态机的基本格式&#xff1a; 概念&#xff1a; 状态机&#xff0c;全称是有限状态机&#xff08;Fin…

再学C语言29:函数——概述

C的设计原则是把函数作为程序的构成模块 函数&#xff08;function&#xff09;&#xff1a;用于完成特定任务的程序代码的自包含单元 使用函数的好处&#xff1a; 1&#xff09;函数的使用可以省去重复代码的编写&#xff0c;尤其是程序中需要多次使用某种特定的功能时&…

unity日记4(鼠标键盘交互、实例)

目录 鼠标事件 鼠标点击、抬起、长按事件 键盘事件 键盘点击、抬起、长按事件 键盘键位替换 实例&#xff1a;鼠标-音乐播放/暂停 实例&#xff1a;调用其他对象的组件&#xff08;双方法&#xff09; 实例&#xff1a;调整其他对象的公有参数 鼠标事件 鼠标点击、抬起、长…

实体关系抽取

关系抽取分为pipeline型和联合&#xff08;Joint&#xff09;抽取。 pipeline形式&#xff1a; 指把关系抽取&#xff0c;拆分成多个任务&#xff0c;如【先抽Subject&#xff0c;再一起抽Predict和Object】&#xff08;CasRel&#xff09;、【先判断Predict&#xff0c;再一…

『博客专家』- 你申请了吗?

目录为什么要申请专家博客&#xff1f;个人申请专家博客的流程&#xff1f;个人申请经历7月20日7月20日7月22日7月27日8月2日8月7日8月9日9月26日10月23日10月28日【补】12月5日【补】12月23日总结提一盏读书灯,去翻山越岭; 为什么要申请专家博客&#xff1f; 每次看到厉害的博…

Java中ArrayList如何删除指定位置的元素

目标&#xff1a;list中有0到39共40个元素&#xff0c;删除其中索引是10、20、30的元素 方案一&#xff1a;使用普通for循环从前往后遍历再删除 初始化List列表 List<String> list new ArrayList<>(); for (int i 0; i < 40; i) {list.add("element&qu…

Leetcode 剑指 Offer II 009. 乘积小于 K 的子数组

题目难度: 中等 原题链接 今天继续更新 Leetcode 的剑指 Offer&#xff08;专项突击版&#xff09;系列, 大家在公众号 算法精选 里回复 剑指offer2 就能看到该系列当前连载的所有文章了, 记得关注哦~ 题目描述 给定一个正整数数组 nums 和整数 k &#xff0c;请找出该数组内乘…

处方眼镜镜片在线定制类跨境电商独立站怎么做?

对于处方眼镜镜片&#xff0c;有很多的参数&#xff0c;对于在线类跨境电商商城&#xff0c;需要用户一步一步的提交很多的眼镜参数&#xff0c;下面是fecify眼镜镜片参数的定制过程, fecify的眼镜定制插件提供强有力的支持&#xff0c;下面是处方眼镜镜片在线定制类跨境电商独…

为什么Windows错误报告叫作Dr. Watson?

应该有一部分人可能会知道&#xff0c;Windows 错误报告有一个昵称&#xff0c;叫做”Dr. Watson”(华生医生)&#xff0c;没事&#xff0c;你不知道&#xff0c;也没关系。 今天的文章主要是讲讲&#xff0c;这个”Dr. Watson”名称的来历。 和你所猜想的一样&#xff0c;Dr.…

Java高手速成 | Java集合类泛类型

Java高手是这样炼成的。 01、Java集合类包括哪些&#xff1f; 作为学习集合类泛类型的预备知识&#xff0c;图1列出了Java集合类继承图。要学会集合类泛类型&#xff0c;除了懂得集合类外&#xff0c;大家也需 要了解继承的工作原理。图中虚线表示Collection是一个接口。 02…

Java-性能分析监控工具

Java监控和管理 Java监控和管理API Java Standard Edition&#xff08;Java SE&#xff09;平台提供的监控和管理技术 - JMX&#xff08;Java Management Extensions&#xff09; 技术。 Java SE 中包含了用于监控和管理的&#xff08;java.lang.management&#xff09;API&…

RabbitMQ 总结一(简介、安装、Demo)

目录 什么是MQ RabbitMQ和netty是什么关系 作用 流量削峰 应用解耦 异步处理 MQ的构成 生产者 交换机 队列 消费者 下载安装 案例Demo producer 第一步&#xff0c; 定义好连接的信息并且拿到连接&#xff0c;一般一个consumer/ producer 和broker只会建立一条连…

mysql之日志

前言 一条数据在更新过程当中&#xff0c;如果中途 mysql crash 了&#xff0c;mysql 是如何保证数据的一致性和持久性的&#xff1f;在这个过程中 mysql 的日志系统起到了至关重要的作用。本文将会介绍 mysql 中的 undo log、redo log 和 bin log 在这其中的作用。 buffer p…

230109-MacOS解决brew安装慢的问题

MacOS解决brew安装慢的问题 原文请移步参考&#xff1a; https://www.zhihu.com/question/46963138 cd "$(brew --repo)" git remote set-url origin https://mirrors.ustc.edu.cn/brew.gitecho export HOMEBREW_BOTTLE_DOMAINhttps://mirrors.ustc.edu.cn/homebrew…

2022年度大赏 | UWA问答精选

UWA每周推送的知识型栏目《厚积薄发 | 技术分享》已经伴随大家走过了304个工作周。精选了2022年十大精彩问答分享给大家&#xff0c;期待2022年UWA问答继续有您的陪伴。 Q1&#xff1a;动态获取URP设置里自定义的RenderFeatures 我们在URP项目中自定义了多个RenderFeatures去实…

2022年度总结,以及2023的全新展望

时光总是在你的不经意间流逝&#xff0c;无法挽留&#xff1b;留得住的是你过去的努力和回忆&#xff0c;它也许充斥着快乐、忧伤、病痛等等。俗话说得好“笑一笑十年少”&#xff0c;那么我希望与快乐随行&#xff0c;让痛苦尘封记忆。让我们总结过去&#xff0c;展望未来&…

Python tkinter -- 第18章 画布控件之矩形

18.2.20 create_rectangle(bbox, **options) 根据限定矩形 bbox&#xff0c;在画布上创建一个矩形。新创建的对象位于显示的最前端。 &#xff08;1&#xff09;bbox&#xff1a;定义要创建对象的边界(x1, y1, x2, y2) &#xff08;2&#xff09;options&#xff1a; 选项的具体…

ICESat数据下载

ICESat数据下载1. ICESat简介2. ICESat数据产品2.1 GLA01数据2.2 GLA14数据3. 数据下载4. 总结1. ICESat简介 2003年美国国家航空航天局NASA ( National Aeronautics and SpaceAdministration)发射冰、云和陆地高程卫星ICESat&#xff0c;其上搭载的地球科学激光测高系统GLAS是…

基于YOLOv5的智能人脸数据标注工具源码,实现人脸数据标注自动化,可导出PASCAL VOC XML、MS COCO JSON

基于YOLOv5的智能人脸数据标注工具&#xff0c;实现人脸数据标注自动化 可自定义人脸检测模型、可导出多种格式标签&#xff0c;包括PASCAL VOC XML、MS COCO JSON、YOLO TXT 下载地址&#xff1a;基于YOLOv5的智能人脸数据标注工具源码&#xff0c;实现人脸数据标注自动化 …

智能黑白图像自动上色——C++实现

前言 《Colorful Image Colorization》是加里福利亚大学Richard Zhang发表在ECCV 2016上的文章&#xff0c;论文主要解决的问题是给灰度图的自动着色&#xff0c;算法并不是为恢复灰度图的真实颜色&#xff0c;而是用灰度图中物体的纹理、语义等信息作为线索&#xff0c;来预测…