vue3+Ts+elementPlus二次封装Table分页表格,表格内展示图片、switch开关、支持

目录

一.项目文件结构

二.实现代码

1.子组件(表格组件)

 2.父组件(使用表格)


一.项目文件结构

1.表格组件(子组件)位置

2.使用表格组件的页面文件(父组件)位置

3.演示图片位置

elementPlus表格 Table 表格 | Element Plus

4.笑果演示

表格笑果

点击图片放大显示笑果

二.实现代码

1.子组件(表格组件)

1. src/views/Table.vue html部分

<!-- 表格区域 传值格式 -->
<!-- 单行文字:{ prop: 'inventory', label: '库存', width: '90' }, -->
<!-- 图片格式:{ prop: 'profile_picture_url', label: '商品主图', width: '110', isImg: true, height: 50 }, -->
<!-- 双行文字格式:{ prop: 'information', label: '商品信息', width: '140', doubleRow: true, text1: '货号', text2: '售价' }, -->
<!-- 开关格式:{ prop: 'listed', label: '是否上架', width: '110', isSwitch: true, }, -->
<el-table class="" v-loading="tableLoading" element-loading-text="Loading...":element-loading-spinner="svg" element-loading-svg-view-box="-10, -10, 50, 50"element-loading-background="rgba(122, 122, 122, 0.8)" border :data="paginatedData":default-sort="{ prop: 'date', order: 'descending' }" height="calc(100vh - 235px)":show-overflow-tooltip="true" @selection-change="handleSelectionChange"><el-table-column v-if="isSelected" type="selection" :selectable="selectable" width="55" /><el-table-column fixed align="center" label="序号" width="60"><template #default="scope">{{ scope.$index + 1 }}</template></el-table-column><el-table-column align="center" sortable v-for="(i, n) in columns" :key="n" :prop="i.prop" :label="i.label":formatter="i.formatter" :width="i.width"><template #default="scope"><!-- 当表头数据中有isImg为true时,使单元格展示图片(点击事件为放大显示) --><img class="image" v-if="i.isImg && scope.row[i.prop]" :src="scope.row[i.prop]" alt=""draggable="false" :style="`width: ${i.height}px; height: ${i.height}px`"@click="handleImageClick(scope.row[i.prop])" /><img v-else-if="i.isImg && !scope.row[i.prop]" src="@/assets/image/giegie.jpg" alt=""draggable="false" :style="`width: ${i.height}px; height: ${i.height}px`" /><span v-else-if="i.doubleRow"><span class="doubleRow">{{ i.text1 + ': ' }}</span> {{ scope.row.information?.text1 ?scope.row.information.text1 : '-' }}<br><span class="doubleRow">{{ i.text2 + ': ' }}</span> {{ scope.row.information?.text2 ?scope.row.information.text2 : '-' }}</span><el-switch v-else-if="i.isSwitch" active-text="" inactive-text="" active-color="#2fa1f1"inactive-color="#9c9c9c" v-model="scope.row[i.prop]" @change="handleStatusChange(scope.row)" /><span v-else>{{ formatCell(i, scope.row) }}</span></template></el-table-column><!-- 固定列 --><el-table-column v-if="isFixedColumn" fixed="right" align="center" label="操作" width="100"><template #default="scope"><el-button link type="primary" size="small" @click="btnListTable[0].click(scope.row, 1)">{{btnListTable[0].name}}</el-button><el-popover placement="bottom-start" trigger="click":popper-style="{ minWidth: '55px', padding: '10', width: 'auto', cursor: 'pointer' }"><template #reference><el-button link type="primary" size="small">更多</el-button></template><div><el-button v-for="(i, n) in btnListTable2" :key="n" link type="primary" size="small"@click="i.click(scope.row, 1)">{{i.name }}</el-button></div></el-popover></template></el-table-column></el-table>

js部分

<script setup lang='ts'>
import { ref, computed, defineProps, onMounted, defineEmits } from 'vue';
// 父传子
const props = defineProps({columns: {// 表头数据type: Array,validator: () => {return [];}},paginatedData: {// 表格数据type: Array,validator: () => {return [];}},btnListTable: {// 按钮组type: Array,validator: () => {return [];}},isFixedColumn: {// 是否有操作列type: Boolean,default: true},isSelected: {// 是否有选择框type: Boolean,default: false},tableLoading: {// 是否加载中type: Boolean,default: false,},
});// 操作列 更多按钮组
const btnListTable2 = ref(props.btnListTable.slice(1))
// 多选
interface User {id: numberdate: stringname: stringaddress: string
}
// 选择的内容
const multipleSelection = ref<User[]>([])
const selectable = (row: User) => ![1, 2].includes(row.id)
const handleSelectionChange = (val: User[]) => {multipleSelection.value = val
}
// 分页
const currentPage = ref(1);
const pageSize = ref(10);
const disabled = ref(false)
const background = ref(false)
const enlargedImageUrl = ref('');
const dialogVisible = ref(false);// 点击图片事件
const handleImageClick = (imageUrl: any) => {enlargedImageUrl.value = imageUrl;dialogVisible.value = true;
}// 子传父
const def = defineEmits(['pageSize', 'currentPage', 'switch']);// 分页事件 val: number
const handleSizeChange = () => {def('pageSize', pageSize.value)
}
const handleCurrentChange = () => {def('currentPage', currentPage.value)
}// 计算总数据条数
const totalData = computed(() => props.paginatedData.length);
// 开关事件
const handleStatusChange = ((row: any) => {def('switch', row)
})
// 加载中
const svg = `<path class="path" d="M 30 15L 28 17M 25.61 25.61A 15 15, 0, 0, 1, 15 30A 15 15, 0, 1, 1, 27.99 7.5L 15 15" style="stroke-width: 4px; fill: rgba(0, 0, 0, 0)"/>`// 格式化单元格内容
const formatCell = (column: any, row: string) => {return column.formatter ? column.formatter(row) : row[column.prop];
}
</script>

 2.父组件(使用表格)

1.src/views/Dashboard.vue html部分

<template><div><Table :columns="columns" :paginatedData="paginatedData" :btnListTable="btnListTable":isFixedColumn="true" :tableLoading="loading" @pageSize="handlePageSize" @currentPage="handleCurrentPage"></Table></div>
</template>

 2.js部分

<script setup lang='ts'>
import { ref, reactive } from 'vue'
import type { FormRules } from 'element-plus'
import Table from '../components/Table.vue';
import DialogCom from '../components/DialogCom.vue';
import { list } from '../api/api.ts'
import { require } from '@/utils/require';
// 表格相关 开始
const loading = false
// 表头数据
const columns = ref([{ prop: 'user_id', label: '用户ID', width: 130 },{ prop: 'username', label: '用户名', width: 120 },{ prop: 'email', label: '邮件地址', width: 200 },{ prop: 'phone_number', label: '手机号码', width: 170 },{ prop: 'full_name', label: '真实姓名', width: 120 },{ prop: 'date_of_birth', label: '生日', width: 140 },{ prop: 'gender', label: '性别', width: 100 },{ prop: 'listed', label: '是否打篮球', width: '130', isSwitch: true, },{ prop: 'profile_picture_url', label: '头像', width: 90, isImg: true, height: 20 },// 当是否激活为true时,显示"是"{ prop: 'is_active', label: '是否激活', width: 120, formatter: (row: any) => row.is_active ? '是' : '否' },{ prop: 'created_at', label: '创建时间', width: 180, formatter: (row: any) => formattedDateTime(row.created_at) },{ prop: 'updated_at', label: '更新时间', width: 180 },
]);
// 表格数据
const paginatedData = ref([{ user_id: 'ID', username: '苏珊', email: 'singJumpRapBasketball@ikun.com', is_active: true, created_at: '2023-10-05T14:48:00.000Z', listed: true },{ user_id: 'ID', username: '打球被笑两年半', email: 'kunkun@ikun.com', is_active: false, created_at: '2023-10-05T14:48:00.000Z', profile_picture_url: require('@/assets/image/giegie.jpg') },
]);
// 查询条件
const formBtnList = reactive({pageSize: 10,currentPage: 1,
})
// 操作列按钮事件
const pricingDetail = () => {console.log('pricingDetail')
}
const reject = () => {console.log('reject')
}
// 操作列按钮组
const btnListTable = ref([{ name: '编辑', type: 'primary', click: pricingDetail },{ name: '添加账户', type: 'primary', click: reject },{ name: '导出', type: 'primary', click: reject },
])
// 处理日期时间 (ISO 8601 格式 如:2023-10-05T14:48:00.000Z )
const formattedDateTime = (dateData: string) => {const date = new Date(dateData);const year = date.getFullYear();const month = String(date.getMonth() + 1).padStart(2, '0'); // 月份从0开始,需要加1const day = String(date.getDate()).padStart(2, '0');const hours = String(date.getHours()).padStart(2, '0');const minutes = String(date.getMinutes()).padStart(2, '0');const seconds = String(date.getSeconds()).padStart(2, '0');return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
}
// 分页事件触发
const handlePageSize = (pageSize: number) => {// 每页大小// console.log('handlePageSize', pageSize);formBtnList.pageSize = pageSizehandInquire()
};
const handleCurrentPage = (currentPage: number) => {// 页码// console.log('handleCurrentPage', currentPage);formBtnList.currentPage = currentPagehandInquire()
};
// 表格相关 结束

以上,感谢观看,欢迎指正

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

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

相关文章

ModBus TCP/RTU互转(主)(从)|| Modbus主动轮询下发的工业应用 || 基于智能网关的串口服务器进行Modbus数据收发的工业应用

目录 前言 一、ModBus TCP/RTU互转&#xff08;从&#xff09;及应用|| 1.1 举栗子 二、ModBus TCP/RTU互转&#xff08;主&#xff09; 2.1 举栗子 三、ModBus 主动轮询 3.1 Modbus主动轮询原理 3.2 Modbus格式上传与下发 3.2.1.设置Modbus主动轮询指令 3.2.2 设…

Elasticsearch 在航空行业:数据管理的游戏规则改变者

作者&#xff1a;来自 Elastic Adam La Roche 数字化客户体验不再是奢侈品&#xff0c;而是欧洲航空公司必不可少的需求。它推动了客户满意度&#xff0c;提升了运营效率&#xff0c;并创造了可持续的竞争优势。随着行业的不断发展&#xff0c;优先投资前沿数字技术和平台的航空…

CXL协议之FM(Fabric Management)解释

CXL协议中的FM功能详解 1. FM的核心作用 FM是CXL&#xff08;Compute Express Link&#xff09;架构中的核心管理实体&#xff0c;负责协调和管理CXL设备之间的通信、资源分配及拓扑结构。其核心功能包括&#xff1a; 设备发现与枚举&#xff1a;识别CXL拓扑中的设备&#x…

html5基于Canvas的经典打砖块游戏开发实践

基于Canvas的经典打砖块游戏开发实践 这里写目录标题 基于Canvas的经典打砖块游戏开发实践项目介绍技术栈核心功能实现1. 游戏初始化2. 游戏对象设计3. 碰撞检测系统4. 动画系统5. 用户界面设计 性能优化1. 渲染优化2. 内存管理 项目亮点技术难点突破项目总结 项目介绍 在这个…

IDEA的常用设置与工具集成

简介 IDEA是捷克JetBrains公司推出的一款Java集成开发环境&#xff0c;在业内被公认为最好的Java开发工具之一&#xff0c;尤其在智能代码助手、代码自动提示、重构、J2EE支持、Ant、Junit、CVS整合、代码审查、创新的GUI设计等方面的功能可以说是超强的。 官网&#xff1a;ht…

Golang | 每日一练 (6)

&#x1f4a2;欢迎来到张胤尘的技术站 &#x1f4a5;技术如江河&#xff0c;汇聚众志成。代码似星辰&#xff0c;照亮行征程。开源精神长&#xff0c;传承永不忘。携手共前行&#xff0c;未来更辉煌&#x1f4a5; 文章目录 Golang | 每日一练 (6)题目参考答案什么是内存逃逸&am…

Qt窗口控件之颜色对话框QColorDialog

颜色对话框QColorDialog QColorDialog 是 Qt 内置的颜色对话框&#xff0c;它允许用户选择一个颜色&#xff0c;并通过接口获取颜色的值&#xff0c;进行进一步设置。 获取QColorDialog颜色 QColorDialog 可以使用堆创建&#xff0c;挂载对象树的方式。但它更适合使用它的静…

Windows Docker 报错: has no HTTPS proxy,换源

pull python 3.7报错&#xff1a; 尝试拉取Docker 测试库hello world也失败 尝试使用临时镜像源&#xff0c;可以成功拉取&#xff1a; sudo docker pull docker.m.daocloud.io/hello-world说明确实是网络问题&#xff0c;需要配置镜像源&#xff0c;为了方便&#xff0c;在d…

Unity Shader 学习16:全局光照 概念理解

- 全局光照 直接光 间接光&#xff0c;在没有开启GI的情况下是不计算间接光的&#xff08;如果放了光照探针 倒是可以模拟间接光 <光照探针只影响动态物体>&#xff09;&#xff1b; - 处理对象&#xff1a;静态物体(static) 、 非静态(动态)物体&#xff1b; - 计算方…

【蓝桥杯python研究生组备赛】005 数学与简单DP

题目1 01背包 有 N 件物品和一个容量是 V 的背包。每件物品只能使用一次。 第 i 件物品的体积是 vi&#xff0c;价值是 wi。 求解将哪些物品装入背包&#xff0c;可使这些物品的总体积不超过背包容量&#xff0c;且总价值最大。 输出最大价值。 输入格式 第一行两个整数&a…

吴恩达机器学习笔记复盘(六)梯度下降算法

简介 梯度下降&#xff08;Gradient Descent&#xff09;是一种常用的优化算法&#xff0c;广泛应用于机器学习、深度学习等领域&#xff0c;在这里是用于求J&#xff08;w,b&#xff09;局部最小值。 我自己觉得这样说有点过于抽象。换个直观点的说法就是&#xff0c;一个人…

【Golang那些事】go1.22和1.23 更新重点及测评

好久没有写文章了&#xff0c;攒了一年的Golang版本特性的技术点以及踩过的坑&#xff0c;那就在新年第一篇的文章中做一个总结吧&#xff1a; 一、关于迭代器 (一)迭代器去掉了共享共享内存 一个经典的面试题 说到Golang经典的面试题&#xff0c;大家可能都刷到过很多&…

【css酷炫效果】纯CSS实现照片堆叠效果

【css酷炫效果】纯CSS实现照片堆叠效果 缘创作背景html结构css样式完整代码基础版进阶版(增加鼠标悬停查看) 效果图 想直接拿走的老板&#xff0c;链接放在这里&#xff1a;https://download.csdn.net/download/u011561335/90492022 缘 创作随缘&#xff0c;不定时更新。 创…

labview与西门子1500plc进行S7通讯(仿真效果)

环境&#xff1a; 1.博图V16 2.S7-PLCSIM Advanced V3.0 3.labview2020 4.HslCommunication的dll文件 运行效果图 通过使用HslCommunication的库文件来对西门子plc进行通讯 labview代码 代码打包 通过网盘分享的文件&#xff1a;labview进行s7通讯测试.rar 链接: https:/…

[蓝桥杯 2023 省 B] 飞机降落(不会dfs的看过来)

[蓝桥杯 2023 省 B] 飞机降落 题目描述 N N N 架飞机准备降落到某个只有一条跑道的机场。其中第 i i i 架飞机在 T i T_{i} Ti​ 时刻到达机场上空&#xff0c;到达时它的剩余油料还可以继续盘旋 D i D_{i} Di​ 个单位时间&#xff0c;即它最早可以于 T i T_{i} Ti​ 时刻…

实验1:Vue基础实验

Web前端开发技术实验报告 实验1&#xff1a;Vue基础实验 一、实验目的&#xff1a; 掌握Vue实例的创建方法理解并初步掌握Vue实例的生命周期及钩子函数的使用掌握计算属性与侦听器使用方法 二、实验要求&#xff1a; 掌握Vue的基本语法及使用。编写程序并调试&#xff0c;完…

Spring Cloud 服务监控 - Sleuth + Zipkin 全链路追踪实战

一、为何需要全链路追踪&#xff1f; 在微服务架构中&#xff0c;用户请求通常涉及多个服务的交互&#xff08;如订单→支付→库存&#xff09;。这使得性能瓶颈和故障排查变得更加复杂。传统的日志分析面临两大核心挑战&#xff1a; • 性能瓶颈模糊&#xff1a;当响应延迟增…

数据类设计_图片类设计之6_矩阵图形类设计(前端架构)

前言 学的东西多了,要想办法用出来.C和C是偏向底层的语言,直接与数据打交道.尝试做一些和数据方面相关的内容 引入 接续上一篇,讨论矩阵图形类设计 方法论-现在能做什么 这段属于聊天内容---有句话是这么说的&#xff1a;不要只埋头拉车&#xff0c;还要抬头看路。写代码也是…

OpenCV图像拼接(1)概述

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 此图说明了在Stitcher类中实现的拼接模块流程。使用该类&#xff0c;可以配置/移除某些步骤&#xff0c;即根据特定需求调整拼接流程。流程中的所…

【开原宝藏】30天学会CSS - DAY1 第一课

下面提供一个由浅入深、按步骤拆解的示例教程&#xff0c;让你能从零开始&#xff0c;逐步理解并实现带有旋转及悬停动画的社交图标效果。为了更简单明了&#xff0c;以下示例仅创建四个图标&#xff08;Facebook、Twitter、Google、LinkedIn&#xff09;&#xff0c;并在每一步…