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.pswp.cn/diannao/73869.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/73869.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/73869.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

[特殊字符]1.2.1 新型基礎設施建設

&#x1f680; 新型基礎設施建設全解析 &#x1f31f; 核心概念與定義 維度詳細內容定義以新發展理念為引領&#xff0c;以技術創新為驅動&#xff0c;以信息網絡為基礎&#xff0c;提供數字轉型、智能升級、融合創新服務的基礎設施體系。提出背景2018年中央經濟工作會議首次提…

SQL Server數據庫慢SQL調優

SQL Server中慢SQL會顯著降低系統性能并引發級聯效應。首先&#xff0c;用戶直接體驗響應時間延長&#xff0c;核心業務操作&#xff08;如交易處理、報表生成&#xff09;效率下降&#xff0c;導致客戶滿意度降低甚至業務中斷。其次&#xff0c;資源利用率失衡&#xff0c;CPU…

【安全運營】安全運營關于告警降噪的一些梳理

目錄 前言一、智能技術層面1、機器學習和 AI 模型訓練2、攻擊成功判定 二、多源關聯分析1、多源設備關聯&#xff08;跨設備日志整合&#xff09;2、上下文信息增強 三、業務白名單和策略優化1、動態白名單機制2、閾值和規則調整 四、自動化和流程化1、告警歸并與去重2、同類型…

逆向中常見的加密算法識別

1、base64及換表 base64主要是將輸入的每3字節&#xff08;共24bit&#xff09;按照每六比特分成一組&#xff0c;變成4個小于64的索引值&#xff0c;然后通過一個索引表得到4個可見的字符。 索引表為一個64字節的字符串&#xff0c;如果在代碼中發現引用了這個索引表“ABCDEF…

《UNIX網絡編程卷1:套接字聯網API》第2章 傳輸層:TCP、UDP和SCTP

《UNIX網絡編程卷1&#xff1a;套接字聯網API》第2章 傳輸層&#xff1a;TCP、UDP和SCTP 2.1 傳輸層的核心作用與協議選型 傳輸層是網絡協議棧中承上啟下的核心層&#xff0c;直接決定應用的通信質量。其主要職責包括&#xff1a; 端到端通信&#xff1a;屏蔽底層網絡細節&am…

Eclipse 創建 Java 類

Eclipse 創建 Java 類 引言 Eclipse 是一款功能強大的集成開發環境(IDE),被廣泛用于 Java 開發。本文將詳細介紹如何在 Eclipse 中創建 Java 類,包括配置開發環境、創建新項目、添加類以及編寫類代碼等步驟。 配置 Eclipse 開發環境 1. 安裝 Eclipse 首先,您需要在您…

汽車安全確認等級-中國等保

1、概念解析 網絡安全保證等級&#xff08;Cybersecurity Assurance Level&#xff09;通常指在不同標準或框架下&#xff0c;根據系統或數據的敏感性、重要性以及潛在風險劃分的等級&#xff0c;用于指導組織采取相應的安全防護措施。以下是幾個常見的網絡安全保證等級體系及…

藍橋杯練習day2:執行操作后的變化量

題意 存在一種僅支持 4 種操作和 1 個變量 X 的編程語言&#xff1a; X 和 X 使變量 X 的值 加 1 –X 和 X-- 使變量 X 的值 減 1 最初&#xff0c;X 的值是 0 給你一個字符串數組 operations &#xff0c;這是由操作組成的一個列表&#xff0c;返回執行所有操作后&#xff…

【機器學習chp14 — 2】生成式模型—變分自編碼器VAE(超詳細分析,易于理解,推導嚴謹,一文就夠了)

目錄 二、變分自編碼器 VAE 1、自編碼器 AE &#xff08;1&#xff09;自編碼器的基本結構與目標 1.1 編碼器-解碼器結構 1.2 目標函數&#xff1a;重構誤差最小化 &#xff08;2&#xff09;自編碼器與 PCA 的對比 2.1 PCA 與線性降維 2.2 非線性映射的優勢 &#xf…

Linux 一步部署DHCP服務

#!/bin/bash #腳本作者和日期 #author: PEI #date: 20250319 #檢查root權限 if [ "$USER" ! "root" ]; then echo "錯誤&#xff1a;非root用戶&#xff0c;權限不足&#xff01;" exit 0 fi #防火墻與高級權限 systemctl stop firewa…

【RHCE】awk文本處理

目錄 基本介紹 命令格式 awk基本使用 命令行讀取程序腳本 數據字段變量 腳本中使用多個命令 文件中讀取程序 處理數據前運行腳本&#xff08;BEGIN&#xff09; 處理數據后運行腳本&#xff08;END&#xff09; awk高級用法 變量 內建變量 自定義變量 數組 定義…

Vue3 核心特性解析:Suspense 與 Teleport 原理深度剖析

Vue3 核心特性解析&#xff1a;Suspense 與 Teleport 原理深度剖析 一、Teleport&#xff1a;突破組件層級的時空傳送 1.1 實現原理圖解 #mermaid-svg-75dTmiektg1XNS13 {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-s…

工業界處理 Atomic 操作的優化策略

在產業界&#xff0c;處理 atomic 操作 時&#xff0c;通常會根據具體情境選擇不同的策略&#xff0c;主要取決于以下三個因素&#xff1a; 內存一致性需求&#xff1a;是否需要確保 所有線程&#xff08;threads&#xff09; 都能看到最新的變量值。性能需求&#xff1a;是否…

Python功能完美的寶庫——內置的強大“武器庫”builtins

builtins模塊包含了Python大量的內置對象&#xff08;函數、異常和類型等&#xff09;&#xff0c;她是Python的內置武器庫&#xff0c;堪稱功能完美的寶庫。 筆記模板由python腳本于2025-03-19 08:16:27創建&#xff0c;本篇筆記適合喜歡探究python的coder翻閱。 【學習的細節…

三分鐘掌握視頻分辨率修改 | 在 Rust 中優雅地使用 FFmpeg

前言 在視頻處理領域&#xff0c;調整視頻分辨率是一個繞不過去的需求。比如&#xff0c;你可能需要將一段視頻適配到手機、平板或大屏電視上&#xff0c;或者為了節省存儲空間和網絡帶寬而壓縮視頻尺寸。然而&#xff0c;傳統的FFmpeg命令行工具雖然功能強大&#xff0c;但復…

PyTorch 深度學習實戰(17):Asynchronous Advantage Actor-Critic (A3C) 算法與并行訓練

在上一篇文章中&#xff0c;我們深入探討了 Soft Actor-Critic (SAC) 算法及其在平衡探索與利用方面的優勢。本文將介紹強化學習領域的重要里程碑——Asynchronous Advantage Actor-Critic (A3C) 算法&#xff0c;并展示如何利用 PyTorch 實現并行化訓練來加速學習過程。 一、A…

【深度學習】多目標融合算法(五):定制門控網絡CGC(Customized Gate Control)

目錄 一、引言 二、CGC&#xff08;Customized Gate Control&#xff0c;定制門控網絡&#xff09; 2.1 技術原理 2.2 技術優缺點 2.3 業務代碼實踐 2.3.1 業務場景與建模 2.3.2 模型代碼實現 2.3.3 模型訓練與推理測試 2.3.4 打印模型結構 三、總結 一、引言 上一…

在線pdf處理網站合集

1、PDF24 Tools&#xff1a;https://tools.pdf24.org/zh/ 2、PDF派&#xff1a;https://www.pdfpai.com/ 3、ALL TO ALL&#xff1a;https://www.alltoall.net/ 4、CleverPDF&#xff1a;https://www.cleverpdf.com/cn 5、Doc Small&#xff1a;https://docsmall.com/ 6、Aconv…

網絡編程-實現客戶端通信

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/socket.h> #include <netinet/in.h> #include <sys/select.h>#define MAX_CLIENTS 2 // 最大客戶端連接數 #define BUFFER_SI…

力扣100二刷——圖論、回溯

第二次刷題不在idea寫代碼&#xff0c;而是直接在leetcode網站上寫&#xff0c;“逼”自己掌握常用的函數。 標志掌握程度解釋辦法?Fully 完全掌握看到題目就有思路&#xff0c;編程也很流利??Basically 基本掌握需要稍作思考&#xff0c;或者看到提示方法后能解答???Sl…