vue-next-admin vue3.x版本,table自定义

vue3.x版本,将table进行了封装。使用起来更方便了。但是,有时候我们需要将一组信息显示到一列中。所以我将其进行了简单的二次改造。支持table-column自定义。
table改造代码

<template><div class="table-container"><el-table:data="data":border="setBorder"v-bind="$attrs"row-key="id"stripestyle="width: 100%"v-loading="config.loading"@selection-change="onSelectionChange"><el-table-column type="selection" :reserve-selection="true" width="30" v-if="config.isSelection" /><el-table-column type="index" label="序号" width="60" v-if="config.isSerialNo" /><el-table-columnv-for="(item, index) in setHeader":key="index"show-overflow-tooltip:prop="item.key":width="item.colWidth":label="item.title"><template v-slot="scope"><template v-if="item.isCustom"><slot :name="item.key" :row="scope.row"/></template><template v-else><template v-if="item.type === 'image'"><el-image:style="{ width: `${item.width}px`, height: `${item.height}px` }":src="scope.row[item.key]":zoom-rate="1.2":preview-src-list="[scope.row[item.key]]"preview-teleportedfit="cover"/></template><template v-else>{{ scope.row[item.key] }}</template></template></template></el-table-column><el-table-column label="操作" min-width="80" v-if="config.isOperate"><template v-slot="scope"><div><slot name="other" :row="scope.row"/><el-button  v-if="config.isEdit" text type="primary" @click="onEditRow(scope.row)">编辑</el-button><el-popconfirm title="确定删除吗?" @confirm="onDelRow(scope.row)" v-if="config.isDel"><template #reference><el-button text type="danger">删除</el-button></template></el-popconfirm></div></template></el-table-column><template #empty><el-empty description="暂无数据" /></template></el-table><div class="table-footer mt15" v-if="!config.hideFooter"><el-paginationv-model:current-page="state.page.pageNumber"v-model:page-size="state.page.pageSize":pager-count="5":page-sizes="[10, 20, 30]":total="config.total"layout="total, sizes, prev, pager, next, jumper"background@size-change="onHandleSizeChange"@current-change="onHandleCurrentChange"></el-pagination><div class="table-footer-tool"><SvgIcon name="iconfont icon-yunxiazai_o" :size="22" title="导出" @click="onImportTable" /><SvgIcon name="iconfont icon-shuaxin" :size="22" title="刷新" @click="onRefreshTable" /><el-popoverplacement="top-end"trigger="click"transition="el-zoom-in-top"popper-class="table-tool-popper":width="300":persistent="false"@show="onSetTable"><template #reference><SvgIcon name="iconfont icon-quanjushezhi_o" :size="22" title="设置" /></template><template #default><div class="tool-box"><el-tooltip content="拖动进行排序" placement="top-start"><SvgIcon name="fa fa-question-circle-o" :size="17" class="ml11" color="#909399" /></el-tooltip><el-checkboxv-model="state.checkListAll":indeterminate="state.checkListIndeterminate"class="ml10 mr1"label="列显示"@change="onCheckAllChange"/><el-checkbox v-model="getConfig.isSerialNo" class="ml12 mr1" label="序号" /><el-checkbox v-model="getConfig.isSelection" class="ml12 mr1" label="多选" /></div><el-scrollbar><div ref="toolSetRef" class="tool-sortable"><div class="tool-sortable-item" v-for="v in header" :key="v.key" :data-key="v.key"><i class="fa fa-arrows-alt handle cursor-pointer"></i><el-checkbox v-model="v.isCheck" size="default" class="ml12 mr8" :label="v.title" @change="onCheckChange" /></div></div></el-scrollbar></template></el-popover></div></div></div>
</template><script setup lang="ts" name="netxTable">
import { reactive, computed, nextTick, ref } from 'vue';
import { ElMessage } from 'element-plus';
import printJs from 'print-js';
import table2excel from 'js-table2excel';
import Sortable from 'sortablejs';
import { storeToRefs } from 'pinia';
import { useThemeConfig } from '/@/stores/themeConfig';
import '/@/theme/tableTool.scss';// 定义父组件传过来的值
const props = defineProps({// 列表内容data: {type: Array<EmptyObjectType>,default: () => [],},// 表头内容header: {type: Array<EmptyObjectType>,default: () => [],},// 配置项config: {type: Object,default: () => {},},// 打印标题printName: {type: String,default: () => '',},
});// 定义子组件向父组件传值/事件
const emit = defineEmits(['delRow', 'pageChange', 'sortHeader']);// 定义变量内容
const toolSetRef = ref();
const storesThemeConfig = useThemeConfig();
const { themeConfig } = storeToRefs(storesThemeConfig);
const state = reactive({page: {pageNumber: 1,pageSize: 10,},selectlist: [] as EmptyObjectType[],checkListAll: true,checkListIndeterminate: false,
});// 设置边框显示/隐藏
const setBorder = computed(() => {return props.config.isBorder ? true : false;
});
// 获取父组件 配置项(必传)
const getConfig = computed(() => {return props.config;
});
// 设置 tool header 数据
const setHeader = computed(() => {return props.header.filter((v) => v.isCheck);
});
// tool 列显示全选改变时
const onCheckAllChange = <T>(val: T) => {if (val) props.header.forEach((v) => (v.isCheck = true));else props.header.forEach((v) => (v.isCheck = false));state.checkListIndeterminate = false;
};
// tool 列显示当前项改变时
const onCheckChange = () => {const headers = props.header.filter((v) => v.isCheck).length;state.checkListAll = headers === props.header.length;state.checkListIndeterminate = headers > 0 && headers < props.header.length;
};
// 表格多选改变时,用于导出
const onSelectionChange = (val: EmptyObjectType[]) => {state.selectlist = val;
};
// 删除当前项
const onDelRow = (row: EmptyObjectType) => {emit('delRow', row);
};
// 编辑当前项
const onEditRow = (row: EmptyObjectType) => {emit('editRow', row);
};
// 分页改变
const onHandleSizeChange = (val: number) => {state.page.pageSize = val;emit('pageChange', state.page);
};
// 分页改变
const onHandleCurrentChange = (val: number) => {state.page.pageNumber = val;emit('pageChange', state.page);
};
// 搜索时,分页还原成默认
const pageReset = () => {state.page.pageNumber = 1;state.page.pageSize = 10;emit('pageChange', state.page);
};
// 导出
const onImportTable = () => {if (state.selectlist.length <= 0) return ElMessage.warning('请先选择要导出的数据');table2excel(props.header, state.selectlist, `${themeConfig.value.globalTitle} ${new Date().toLocaleString()}`);
};
// 刷新
const onRefreshTable = () => {emit('pageChange', state.page);
};
// 设置
const onSetTable = () => {nextTick(() => {const sortable = Sortable.create(toolSetRef.value, {handle: '.handle',dataIdAttr: 'data-key',animation: 150,onEnd: () => {const headerList: EmptyObjectType[] = [];sortable.toArray().forEach((val: string) => {props.header.forEach((v) => {if (v.key === val) headerList.push({ ...v });});});emit('sortHeader', headerList);},});});
};// 暴露变量
defineExpose({pageReset,
});
</script><style scoped lang="scss">
.table-container {display: flex;flex-direction: column;.el-table {flex: 1;}.table-footer {display: flex;.table-footer-tool {flex: 1;display: flex;align-items: center;justify-content: flex-end;i {margin-right: 10px;cursor: pointer;color: var(--el-text-color-regular);&:last-of-type {margin-right: 0;}}}}
}
</style>

使用方式: 配置中增加 isCustom在这里插入图片描述
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Ajax】笔记-POST请求(原生)

POST请求 html <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>AJAX POST 请求</title><…

VScode——NPM脚本窗口找不到

一、问题描述&#xff08;NPM终端在任务栏左侧找不到&#xff09; VScode&#xff08;Visual Studio Code&#xff09;版本&#xff1a;1.79.2 二、解决办法 第一步&#xff1a;通过设置/用户设置/扩展/MPM更改NPM默认配置&#xff0c;如下图所示&#xff1a; 第二步&#xff…

springboot实现全局异常捕获

导言&#xff1a; 为什么要做异常处理&#xff1a; 原因有三&#xff1a; 1、将系统产生的全部异常统一捕获处理。 2、自定义异常需要由全局异常来捕获。 3、JSR303规范的validator参数校验器、参数校验不通过、本身无法使用try…catch 其实对于前后端分离的项目做异常处理…

分布式应用之Zookeeper和Kafka

分布式应用之Zookeeper和Kafka 一、Zookeeper 1.定义 分布式系统管理框架&#xff0c;主要用来解决分布式集群中应用系统的一致性问题 相当于各种分布式应用服务的 注册中心 文件系统 通知机制2.特点 &#xff08;1&#xff09;Zookeeper&#xff1a;一个领导者&#…

【Java基础教程】(十五)面向对象篇 · 第九讲:抽象类和接口——定义、限制与应用的细节,初窥模板设计模式、工厂设计模式与代理设计模式~

Java基础教程之面向对象 第九讲 本节学习目标1️⃣ 抽象类1.1 抽象类定义1.2 抽象类的相关限制1.3 抽象类应用——模板设计模式 2️⃣ 接口2.1 接口定义2.2 接口的应用——标准2.3 接口的应用——工厂设计模式 (Factory)2.4 接口的应用——代理设计模式 (Proxy) 3️⃣ 抽象类与…

数据库的扩展策略

了解不同的数据库扩展技术可以帮助我们选择适合我们需求和目的的合适策略。 因此&#xff0c;在本文中&#xff0c;我们将展示不同的解决方案和技术&#xff0c;用于扩展数据库服务器。它们分为读取和写入策略。 读取/加载 有时我们的应用程序承受着巨大的负载。为了解决这个…

【VSCode | 使用技巧集锦】中文插件突然失效、配置单个工程(工作区)编码

目录 ✨技巧一&#xff1a;中文插件失效的解决办法✨技巧二&#xff1a;配置单个工程(工作区)编码 ✨技巧一&#xff1a;中文插件失效的解决办法 问题描述&#xff1a;VSCode之前安装了中文插件&#xff0c;可以正常汉化&#xff0c;用了一段时间都没问题&#xff0c;今天打开v…

51单片机的智能交通控制系统【含仿真+程序+演示视频带原理讲解】

51单片机的智能交通控制系统【含仿真程序演示视频带原理讲解】 1、系统概述2、核心功能3、仿真运行及功能演示4、程序代码 1、系统概述 该系统由AT89C51单片机、LED灯组、数码管组成。通过Protues对十字路口红绿灯控制逻辑进行了仿真。 每个路口包含了左转、右转、直行三条车道…

【UE4 塔防游戏系列】08-敌人到达终点对玩家造成伤害

目录 效果 步骤 一、敌人到终点时扣除玩家生命值 二、显示玩家生命值 效果 可以看到敌人进入终点后&#xff0c;左上角的玩家生命值会减少。 步骤 一、敌人到终点时扣除玩家生命值 新建一个Actor蓝图类&#xff0c;命名为“BP_EnemyEndPlace”&#xff0c;用来表示终点…

Pytest测试框架搭建需求及实现方案

目录 框架需求及实现方案 框架需求 实现方案 支持接口自动化、Web UI自动化及App自动化# 可以批量运行用例并生成测试报告 测试完成发送邮件 提供灵活的运行方式&#xff0c;如按功能模块运行、按脚本运行、按用例等级运行等等 提供运行日志方便定位问题 支持切换环境 …

三季度上市,比亚迪海豹DM-i内饰官图发布,延续海洋风格

据报道&#xff0c;比亚迪海洋网旗下全新车型海豹 DM-i今日发布了内饰官方图片。新车内部采用了独特的“海洋美学”设计理念&#xff0c;并体现了海洋网最新一代内饰风格。消息称&#xff0c;这款车型将于第三季度上市&#xff0c;定位为中大型混合动力轿车。 值得注意的是&…

MSA【1】:Segment Anything Model for Medical Image Analysis: an Experimental Study

文章目录 前言1. Abstraction & Introduction1.1. Abstraction1.2. Introduction1.2.1. What is SAM?1.2.2. How to segment medical images with SAM? 2. Methodology2.1. SAM is used in the process of segmentation of medical images2.1.1. Semi-automated annotati…