vue3后台管理系统封装的普通表格组件

news2024/11/27 14:44:25

1.普通的表格组件效果

ComtableListR.vue组件

<template>
  <div class="tableBox">
    <div class="btn-add">
      <a-space>
        <a-upload v-model:file-list="fileList" v-if="hasImport" name="file" accept=".xls,.xlsx"
          action="" :headers="headers" @change="handleChange">
          <a-button type="primary"> 导入 </a-button>
        </a-upload>
        <a-button type="primary" v-if="hasExport" @click="handleAllExport">导出全部</a-button>
        <a-button type="primary" v-if="allDel">全部删除</a-button>
        <a-button :disabled="dataSource.length === 0 || flagselectedRowKeys" v-if="rowSelection"
          @click="delEvent(selecrowdata, 'many')">批量删除</a-button>
        <a-button :disabled="dataSource.length === 0 || flagselectedRowKeys" v-if="markread"
          @click="handleFlagRead(selecrowdata, 'hasread')">标记已读</a-button>
        <a-button type="primary" v-if="operatingButton?.addbtn" @click="editEvent('add')">{{addbtnName?addbtnName:'添加'}}</a-button>
        <a-button type="primary" v-if="hasgoback" @click="handlegoback">返回</a-button>
      </a-space>
    </div>
    <a-table :dataSource="dataSource" :columns="columns" :loading="loading" :scroll="{ x: tableOtherobj.scroll }"
      :expandIconColumnIndex="expandIconSet.expandIconColumnIndex" :expandIconAsCell="expandIconSet.expandIconAsCell"
      @expand="handleexpand" @expandedRowsChange="expandedRowsChange" :row-selection="rowSelection || markread || rowSelection2
        ? { ...objrowSelection }
        : null
        " :pagination="pagination ? objArray.pagination : false">
      <template #bodyCell="{ column, record, index }">
        <slot name="customtable" :column="column" :record="record"></slot>
        <template v-if="column.key === 'operation'">
          <span>
            <slot name="operation" :column="column" :record="record"></slot>
            <a @click="editEvent('download', record)" v-if="operatingButton?.reportdownload">
              报表下载</a>
            <a-divider type="vertical" v-if="dividerbutton?.reportdownload" />
            <a @click="editEvent('detail', record)" v-if="operatingButton?.detail">
              查看</a>
            <a-divider type="vertical" v-if="dividerbutton?.detail" />
            <a @click="editEvent('edit', record)" v-if="operatingButton?.edit">修改</a>
            <a-divider type="vertical" v-if="dividerbutton?.edit" />
            <a @click="delEvent(record)" v-if="operatingButton?.del" style="color: red">删除</a>
            <a-divider type="vertical" v-if="dividerbutton?.del" />
          </span>
        </template>
        <template v-if="column.key === 'index'">
          <span>{{
            `${(objArray.pagination.current - 1) * objArray.pagination.pageSize +
              index +
              1
              }`
          }}</span>
        </template>
        <template v-if="column.key === objType.typeName && objType.isshow">
          <span :style="{
            color: objTypecolor.isshow
              ? objTypecolor[record[objType.typeName]]
              : null,
          }">{{ objType[record[objType.typeName]] }}</span>
          <!-- <span :style="{color:`#FF0000`}">{{
                        objType[record[objType.typeName]]
                    }}</span> -->
        </template>
        <template v-if="column.key === obj2Type?.typeName && obj2Type?.isshow">
          <span>{{ obj2Type[record[obj2Type.typeName]] }}</span>
        </template>
      </template>
    </a-table>
  </div>
</template>
<script setup>
import { reactive, ref, watch, toRefs } from "vue";



const props = defineProps({
  addbtnName: {
    type: String,
    default: ''
  },
  operatingButton: {
    //操作按钮
    reportdownload: {
      type: Boolean,
      default: false,
    },
    edit: {
      type: Boolean,
      default: true,
    },
    del: {
      type: Boolean,
      default: true,
    },
    detail: {
      type: Boolean,
      default: false,
    },
  },
  dividerbutton: {
    //操作按钮之间的分割线
    reportdownload: {
      type: Boolean,
      default: false,
    },
    edit: {
      type: Boolean,
      default: true,
    },
    del: {
      type: Boolean,
      default: false,
    },
    detail: {
      type: Boolean,
      default: false,
    },
  },

  allDel: {
    //按钮:全部删除
    type: Boolean,
    default: false,
  },
  columns: {
    //表格表头
    type: Array,
    default: [],
  },
  formessagedivider: {
    type: Boolean,
    default: false,
  },
  hasImport: {
    //按钮:导入
    type: Boolean,
    default: false,
  },
  hasExport: {
    //按钮:导出
    type: Boolean,
    default: false,
  },
  markread: {
    // 按钮:标记已读
    type: Boolean,
    default: false,
  },
  hasDetail: {
    //表格详情
    type: Boolean,
    default: false,
  },
  tableOtherobj: {
    type: Object,
    default: {
      // hasAddbtn: true,// 表格上是否有添加按钮
      // hasDetail: false,//操作中是否有详情
      scroll: false, //表格是否有横向滚动,以及x,方向的 值是多少  number
      actionwidth: "120",
    },
  },
  hasedit: {
    //表格修改
    type: Boolean,
    default: true,
  },
  hasdel: {
    //表格删除
    type: Boolean,
    default: true,
  },
  hasseeprocess: {
    //表格查看过程
    type: Boolean,
    default: false,
  },

  pagination: {
    //分页
    type: Boolean,
    default: true,
  },

  // 是否有批量操作
  rowSelection: {
    type: Boolean,
    default: false,
  },
  rowSelection2: {
    // 是否可以选择
    type: Boolean,
    default: false,
  },
  hasgoback: {
    //返回按钮
    type: Boolean,
    default: false,
  },
  searchkey: {
    // 查询的字段
    type: Object,
    default: {},
  },
  objType: {
    //后台返回摸个字段,不能直接显示,而是根据不同值显示对应的其他内容
    type: Object,
    default: {
      isshow: false, //是否显示
      typeName: "type", // 属性值 '需要转义的表格字段,当type=1时显示公司级;当typ=2时显示部门级'
      1: "公司级",
      2: "部门级",
    },
  },
  obj2Type: {
    //页面需要两个字段都用枚举时
    type: Object,
    default: {
      isshow: false, //是否显示
      typeName: "type", // 属性值 '需要转义的表格字段,当type=1时显示公司级;当typ=2时显示部门级'
      1: "公司级",
      2: "部门级",
    },
  },
  objTypecolor: {
    type: Object,
    default: {
      isshow: false, //是否显示
      typeName: "monitorDataReportType", // 属性值 '需要设置颜色的字段'
      day: "#FF0000",
      month: "#FFFF00",
    },
  },
  expandIconSet: {
    // 表格嵌套时,那个控制的展开折叠图表的位置
    type: Object,
    default: {
      expandIconColumnIndex: 2, //想让展开图标放在第几列
      expandIconAsCell: false, 想让展开图标放在第几列 设置的配套属性
    },
  },

  loading: false, //表格loading
});
const {
  objTypecolor,
  obj2Type,
  operatingButton,
  dividerbutton,
  formessagedivider,
  markread,
  columns,
  hasImport,
  hasExport,
  hasDetail,
  tableOtherobj,
  hasedit,
  hasdel,
  hasseeprocess,
  pagination,
  rowSelection,
  hasgoback,
  searchkey,
  objType,
  expandIconSet,
} = toRefs(props);



// 发送给父组件的方法
const emits = defineEmits([
  "openModel",
  "handleDelTable",
  "getData",
  "FlagRead",
  "handleTableRowSelec",
  "exportXlsx",
  "importXlsx",
]);

// 批量删除
let flagselectedRowKeys = ref(true);
let selecrowdata = ref();
const objrowSelection = {
  // selectedRowKeys: selectedRowKeys,

  //selectedRowKeys 选中行的datasource 中元素key的值; selectedRows为所选元素中datasource 是一个数组。
  onChange: (selectedRowKeys, selectedRows) => {
    let falg = selectedRowKeys.length ? false : true;
    flagselectedRowKeys.value = falg;
    selecrowdata.value = [...selectedRowKeys];
    // console.log(`selectedRowKeys: ${selectedRowKeys}`, 'selectedRows: ', selectedRows);
    emits("handleTableRowSelec", selectedRowKeys, selectedRows);
  },
};

// 返回
const handlegoback = () => {
  history.back();
};
// 操作
const editEvent = (param1, param2) => {
  emits("openModel", param1, param2);
};
const delEvent = (param1, param2) => {
  emits("handleDelTable", param1);
};
const handleFlagRead = () => {
  emits("FlagRead", selecrowdata);
};
// 分页方法
let objArray = reactive({
  // 请求参数
  searchParams: {},
  // 分页信息
  pagination: {
    current: 1,
    total: 0,
    pageSize: 25,
    showSizeChanger: true,
    showTotal: (total) => `共 ${total} 条`,
    pageSizeOptions: ['1',"15", "20", "25", "30", "40"],
    onChange: (page, pageSize) => {
      handleSizeChange(page, pageSize);
    },
  },
  // 批量选中
  selectedRowKeys: [],
  // 选中的行数据
  selectedRows: [],
});

const handleSizeChange = (page, pageSize) => {
  if (objArray.pagination.pageSize != pageSize) {
    objArray.pagination.current = 1;
    objArray.pagination.pageSize = pageSize;
  } else {
    objArray.pagination.current = page;
  }
  emits("getData", props.searchkey, objArray.pagination);
};
// 嵌套子表格
const handleexpand = (expanded, record) => {
  console.log(expanded, record, "expanded, record");
};
const expandedRowsChange = (expandedRows) => {
  console.log(expandedRows, "expandedRows");
};

// 导出全部
const handleAllExport = () => {
  emits("exportXlsx");
};
// 导入
const headers = {
  authorization: "authorization-text",
};
const fileList = ref([]);
const handleChange = (info) => {
  if (info.file.status !== "uploading") {
    console.log(info.file, info.fileList);
  }
  if (info.file.status === "done") {
    message.success(`${info.file.name} file uploaded successfully`);
  } else if (info.file.status === "error") {
    message.error(`${info.file.name} file upload failed.`);
  }
  emits("importXlsx", info);
};
const handleImportant = () => { };
const dataSource = ref([]);
const getData = (data, total) => {

  dataSource.value = data;
  objArray.pagination.total = total;
};
const setpage = (pageojb) => {
  objArray.pagination.current = pageojb.current
  objArray.pagination.pageSize = pageojb.pageSize
}
defineExpose({ getData, setpage });
</script>
<style lang="less" scoped>
.btn-add {
  text-align: right;
  /* margin-bottom: 20px; */
  /* margin-top: 20px; */
}

:deep(.ant-select-single:not(.ant-select-customize-input)) {
  .ant-select-selector {
    height: 24px !important;
  }
}

:deep(.ant-select-single) {
  .ant-select-selector {
    .ant-select-selection-item {
      line-height: 22px !important;
    }
  }
}
</style>

 使用:

<ComtableListR ref="tablistRef" :hasImport="false" :loading="loading" :hasExport="false"
      :dividerbutton="dividerbutton" :operatingButton="operatingButton" @getData="getData" :columns="columns"
      @openModel="openModel">
      <template #operation="{ column, record }">
        <a @click="openModal('准则类型', record)"> 准则类型</a>
        <a-divider type="vertical" />
        <a @click="openModal('等级判定', record)"> 等级判定</a>
        <a-divider type="vertical" />
      </template>
    </ComtableListR>
import {
  columns,
  formListEdit,
  dividerbutton,
  operatingButton,
} from "./data";
import ComtableListR from "@/components/ComtableListR.vue";


const getData = async (from, param2) => {
  let params = {
    SkipCount: ((param2?.current ? param2?.current : 1) - 1) * (param2?.pageSize ? param2?.pageSize : 25),
    MaxResultCount: (param2?.pageSize ? param2?.pageSize : 25),
  };
  loading.value = true
  const res = await getRiskEvaluation(params);
  loading.value = false
  tablistRef.value.getData([...res.Items], Number(res.TotalCount));
};

const openModel = (param1, param2) => {
  mainedit.value = true
  switch (param1) {
    case "edit":
      formList.value = [...formListEdit];
      title.value = "修改";
      detailData(param2.Id).then((res) => {
        // res.createtime = dayjs(res.createtime);
        res.RiskEvaluationMethodDisplayName = res?.RiskEvaluationMethod?.DisplayName ? res?.RiskEvaluationMethod?.DisplayName : ""
        refcomDrawer.value.showModal(true, res);
      });
      visible.value = true;
      drawerBtn.value = true;
      break;
  }
};

const openModal = (type, record) => {
  mainedit.value = false
  modalId.value = record.Id
  switch (type) {
    case "准则类型":
      modalTitle.value = type;
      modalRef.value.showModal(true);
      modalColumns.value = typeColumns;
      nextTick(() => {
        getModalData();
      });
      break;
    case "准则配置":
      modalTitle.value = '准则配置';
      modalRef2.value.showModal(true);
      nextTick(() => {
        getConfigData()
      });
      break;
    case "等级判定":
      modalTitle.value = type;
      modalRef.value.showModal(true);
      modalColumns.value = judgeColumns;
      nextTick(() => {
        getModalData();
      });
      break;
  }
};

data.js

export const columns = [
    {
        title: '序号',
        dataIndex: 'index',
        key: 'index', align: 'center',
        width: 80,
        ellipsis: true
    },
    {
        title: '名称',
        dataIndex: 'DisplayName',
        key: 'DisplayName', align: 'center',
        width: 80,
        ellipsis: true
    },
    {
        title: '函数地址',
        dataIndex: 'ResultCalculateApi',
        key: 'ResultCalculateApi', align: 'center',
        width: 80,
        ellipsis: true
    },
    {
        title: '创建人',
        dataIndex: 'CreatorDisplayName',
        key: 'CreatorDisplayName', align: 'center',
        customRender: ({ text ,record}) => {
            // console.log(record,'rrrrrrrrr')
            return  record?.Creator?.DisplayName?record?.Creator?.DisplayName:""
        },
        width: 80,
        ellipsis: true
    },
    {
        title: '创建时间',
        dataIndex: 'CreationTime',
        key: 'CreationTime', align: 'center',
        customRender: ({text})=>{
            return dayjs(text).format('YYYY-MM-DD HH:mm:ss')
        },
        width:160,
        ellipsis: true
    },
    {
        title: '上次修改人',
        dataIndex: 'LastModifierDisplayName',
        key: 'LastModifierDisplayName', align: 'center',
        customRender: ({ text ,record}) => {
            // console.log(record,'rrrrrrrrr')
            return  record?.LastModifier?.DisplayName?record?.LastModifier?.DisplayName:""
        },
        width: 80,
        ellipsis: true
    },
    {
        title: '上次修改时间',
        dataIndex: 'LastModificationTime',
        key: 'LastModificationTime',
        align: 'center',
        customRender: ({ text }) => {
            let onetext=dayjs(text).format('YYYY-MM-DD HH:mm:ss')
            let TwoText= text?onetext :""
            return TwoText
        },
        width: 160,
        ellipsis: true
    },
    { title: "操作", dataIndex: "operation", key: "operation", align: 'center',
    width: 200},
]
// operating button 操作按钮
export const operatingButton = {
    reportdownload: false,
    edit: true,
    del: false,
    detail: false,
    addbtn: false
}
export const dividerbutton = {
    reportdownload: false,
    edit: false,
    detail: false
}

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

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

相关文章

关于Arduino IDE库文件存放路径问题总结(双版本)

在开发过程中,如果不注意,库文件存放路径很乱,如果在转移系统环境时,容易忘记备份。编译过程中出现多个可用引用包的位置,为了解决这些问题,要明白各文件夹的默认路径在哪,区别在哪,如有了解不对的地方请指正。 IDE安装目录(默认C盘,自定义可以其他盘符下)IDE升级可…

动态规划(四) —— 子序列和子串系列问题总结

前言 通过前面有关动态规划经典问题如背包问题、打家劫舍系列问题和股票投资问题的学习相信小伙伴跟荔枝一样对于动态规划题目有了一定的感觉。接下来再这篇文章中荔枝会继续梳理有关动态规划的经典系列问题——子序列和子串问题&#xff0c;给出解题的分析思路和具体的题解&am…

曲阜师范大学2023年暑期大一新生排位赛 题解

目录 A (1). Sum 详细点击&#xff1a;sum //整除分块 B (2). Sort C (3). String //字符串dp D (4). Factor ​​​​​​​ ​​​​​​​ //素数筛变式 E (5). Tree ​​​​​​​ …

复现Nature图表:GSEA分析及可视化包装函数

这篇帖子主要的目的是写一个转录组GSEA分析和可视化通用的函数。起因是我们想要复现一篇文章的GSEA可视化图片&#xff0c;这个Nature文章GSEA可视化挺好的&#xff1a; image.png &#xff08;reference&#xff1a;B-cell-specific checkpoint molecules that regulate anti…

vscode报警和报错没有颜色

前言 解决方法来源 https://www.zhihu.com/question/506531863 解决步骤 安装IPython conda install IPython打开/anaconda3/envs/mmagic3/lib/python3.8/site-packages&#xff0c;然后创建一个文件&#xff0c;sitecustomize.py&#xff0c;里面写入 import sys frome IP…

Python(二十一)intput()函数的高级使用

❤️ 专栏简介&#xff1a;本专栏记录了我个人从零开始学习Python编程的过程。在这个专栏中&#xff0c;我将分享我在学习Python的过程中的学习笔记、学习路线以及各个知识点。 ☀️ 专栏适用人群 &#xff1a;本专栏适用于希望学习Python编程的初学者和有一定编程基础的人。无…

Kafka消息队列基础入门和实战例子

1、Kafka 1.1 Kafka部署配置 1.1.1 下载Kafka 下载Kafka https://kafka.apache.org/downloads.html https://archive.apache.org/dist/kafka/2.4.1/kafka_2.11-2.4.1.tgz下载Scala-2.11版本 Scala-2.11经典版本解压 直接解压到某个目录&#xff0c;可以一起放在Java相关的…

MathType公式编辑器右边选项变灰

今天在写论文的时候&#xff0c;想要给公式添加编号&#xff0c;发现Word中的MathType好多选项都变灰了&#xff0c;然后查找了一些资料&#xff0c;最终解决&#xff0c;这里记录一下&#xff0c;方便以后查阅。 MathType公式编辑器右边选项变灰 问题描述解决方案禁止MathType…

C++---树形DP---树的中心(每日一道算法2023.7.19)

注意事项&#xff1a; 本题为"树形DP—树的最长路径"的近似题&#xff0c;同时涉及到 单链表模拟邻接表存储图 的操作&#xff0c;建议先理解那篇文章。 题目&#xff1a; 给定一棵树&#xff0c;树中包含 n 个结点&#xff08;编号1~n&#xff09;和 n−1 条无向边…

pandas清洗客户编码异常数据

前言 在不同行业中&#xff0c;我们经常会遇到一个麻烦的问题&#xff1a;数据清洗。尤其是当我们需要处理客户编码异常数据时&#xff0c;这个问题变得尤为重要。想象一下&#xff0c;许多银行都是以客户为单位管理数据的&#xff0c;因此每个客户都有一个独特的编码。在处理…

LiveGBS流媒体平台GB/T28181功能-海康NVR摄像机自带物联网卡摄像头注册GB/T28181国标平台看不到设备的时候如何抓包及排查

海康大华宇视华为等硬件NVR摄像机注册到LiveGBS国标平台看不到设备的时候如何抓包及排查 1、设备注册后查看不到1.1、是否是自带物联网卡的摄像头1.2、关闭萤石云1.3、防火墙排查1.4、端口排查1.5、IP地址排查1.6、设备TCP/IP配置排查1.7、设备多网卡排查1.8、设备接入配置参数…

实战:ELK环境部署并采集springboot项目日志

文章目录 前言技术积累ELK组成及功能框架搭建基础 EIK环境搭建elasticsearch配置相关kibana配置相关logstash配置相关elk目录下增加docker-compose文件查看elk目录文件树编排elk springboot集成logstashpom.xmllogback-spring.xml启动项目logstash采集日志 写在最后 前言 相信…

Java8 stream toMap、groupingBy、mapping的综合应用

文章目录 一、stream toMap、groupingBy、mapping的综合应用1、前提准备①、实体类②、数据准备 2、核心代码&#xff1a;3、运行结果 一、stream toMap、groupingBy、mapping的综合应用 1、前提准备 ①、实体类 package com.cfay.demo;import lombok.AllArgsConstructor; i…

LCD拼接屏、LED显示屏和OLED显示屏的主要区别

我们在生活或工作中经常看到大大小小的显示屏&#xff0c;但很多人却分不清楚这些屏到底属于哪一类&#xff0c;今天sostron与大家一起来分享下关于&#xff1a;LCD拼接屏、LED显示屏、OLED透明屏三者的区别。 LCD拼接屏、LED显示屏和OLED显示屏是不同类型的显示技术&#xff0…

【116个】网络安全测试相关面试真题

1、Burpsuite常用的功能是什么&#xff1f; 2、reverse_tcp和bind_tcp的区别&#xff1f; 3、拿到一个待检测的站或给你一个网站&#xff0c;你觉得应该先做什么&#xff1f; 4、你在渗透测试过程中是如何敏感信息收集的&#xff1f; 5、你平时去哪些网站进行学习、挖漏洞提交到…

这样创建客户帮助中心,效果超好!

创建一个有效的客户帮助中心是为了为客户提供优质的支持和服务。在这个数字化时代&#xff0c;客户期望能够快速找到所需的信息&#xff0c;并得到准确和及时的解答。本文将分享创建有效客户帮助中心的最佳实践&#xff0c;帮助您提供出色的客户体验并提升客户满意度。 1. 了解…

Banana Pi M2 Zero 运行 openHAB 回顾

首先我要透露的是&#xff0c;BPI 的工作人员向我发送了一台免费的 BPi M2 Zero 来执行这些测试。我相信我的评论是公平和公正的&#xff0c;但我想坦率地说明这一事实。 硬件简介 与 Raspberry Pi Zero W 相比&#xff0c;Banana Pi BPI-M2 Zero 具有令人印象深刻的规格。以下…

git进阶操作

一、git 基础概念1. 1.1 三种状态&#xff1a; 工作区&#xff08;unstage&#xff09;——已修改&#xff08;modified&#xff09; 暂存区&#xff08;stage&#xff09;——已暂存&#xff08;staged&#xff09; 对象区——已提交&#xff08;commited&#xff09; 工作…

moment.js常见格式化处理各种时间方法

Moment.js 是一个简单易用的轻量级 JavaScript 日期处理类库,提供了日期格式化、日期解析等功能。它支持在浏览器和 NodeJS 两种环境中运行。此类库能够将给定的任意日期转换成多种不同的格式,具有强大的日期计算功能,同时也内置了能显示多样的日期形式的函数。另外,它也支…

博弈论--sg函数

sg函数------ 定义终止状态的SG函数值为0。如果游戏已经结束&#xff0c;即达到了终止状态&#xff0c;那么对应的SG函数值就是0。即先手的sg值为0&#xff0c;则先手必败&#xff0c;否则先手必胜。 如何求sg函数值--------对于每个可能的移动&#xff0c;将后续状态的SG函数…