vue3基于elementplus 簡單實(shí)現(xiàn)表格二次封裝過程
公司渲染表格數(shù)據(jù)時(shí)需要將空數(shù)據(jù)顯示‘-’,并且對于每一列數(shù)據(jù)的顯示也有一定的要求,基于這個(gè)需求對element-plus簡單進(jìn)行了二次封裝。
具體包括以下幾點(diǎn)(持續(xù)更新中):
1.空數(shù)據(jù)顯示‘-’
2.固定表格高度
3.支持多選表格
4. 自定義列寬
<template> <div> <el-table :data="dataSource" v-loading="loading" :height="vdaH" :max-height="vdaH" :fit="fit" :border="border" :header-cell-class-name="headerCellClassName" highlight-current-row :tooltip-options="{ effect: 'dark', placement: 'bottom', showArrow: true, }" show-overflow-tooltip @selection-change="handleSelectionChange" > <el-table-column v-if="isMoreSelect" type="selection" width="55" :selectable="handleSelectable" /> <el-table-column type="index" label="序號(hào)" width="55" /> <template v-for="(column, index) in columns" :key="index"> <el-table-column show-overflow-tooltip v-if="column.scopeVal" :prop="column.prop" :label="column.label" :min-width="column.width || column.label.length * 20 + 20" > <template #default="scope"> <slot :column="column" :record="scope.row" :text="scope.row[column.prop]" :index="dataSource.indexOf(scope.row)" :name="column.prop" > </slot> </template> </el-table-column> <!-- :min-width="column.width || column.label.length * 20 + 20" --> <el-table-column v-else :prop="column.prop" :label="column.label" :min-width=" column.width || getColumnWidth(column.label, column.prop, dataSource) " > <template #default="{ row }"> {{ checkEmpty(row[column.prop]) }} </template> </el-table-column> </template> <!-- 操作 --> <el-table-column v-if="!hideOperation" fixed="right" label="操作" align="center" :width="operationWidth" > <template #default="scope"> <slot v-bind="scope"></slot> </template> </el-table-column> </el-table> <div class="pagination"> <el-pagination v-show="totalNum > 0" @size-change="handleSizeChange" @current-change="handleCurrentChange" v-model:current-page.sync="page" :page-sizes="[10, 20, 50, 100]" v-model:page-size="size" layout="total, sizes, prev, pager, next, jumper" :total="totalNum" background small /> </div> </div> </template> <script lang="ts" setup> import { checkEmpty, getColumnWidth } from "@/utils/util"; const props = defineProps({ dataSource: { type: Array<any>, default: () => [], }, columns: { type: Array<any>, default: () => [], }, vdaH: { type: Number, default: 300, }, hideOperation: { type: Boolean, default: false, }, operationWidth: { type: String, default: "100", }, loading: { type: Boolean, default: false, }, //是否多選顯示 isMoreSelect: { type: Boolean, default: false, }, fit: { type: Boolean, default: true, }, border: { type: Boolean, default: false, }, headerCellClassName: { type: String, default: "custmorTableHeader", }, // 當(dāng)前頁 currentPage: { type: Number, default: 0, }, // 展示頁數(shù) pageSize: { type: Number, default: 0, }, //總頁數(shù) totalNum: { type: Number, default: 0, }, //多選 handleSelection: { type: Function, default: () => {}, }, }); // // 測試列寬 // /** // * el-table擴(kuò)展工具 -- 列寬度自適應(yīng) // * @param {*} prop 字段名稱(string) // * @param {*} records table數(shù)據(jù)列表集(array) // * @returns 列寬(int) // */ // function getColumnWidth(prop: string, records: any) { // const minWidth = 80; // 最小寬度 // const padding = 12; // 列內(nèi)邊距 // const contentWidths = records.map((item: any) => { // console.log("item", item); // console.log("PROP", prop); // const value = item[prop] ? String(item[prop]) : ""; // const textWidth = getTextWidth(value); // return textWidth + padding; // }); // console.log("contentWidths", contentWidths); // let maxWidth = Math.max(...contentWidths); // if (maxWidth > 240) { // maxWidth = 240; // } // return Math.max(minWidth, maxWidth); // } // /** // * el-table擴(kuò)展工具 -- 列寬度自適應(yīng) - 獲取列寬內(nèi)文本寬度 // * @param {*} text 文本內(nèi)容 // * @returns 文本寬度(int) // */ // function getTextWidth(text: string) { // const span = document.createElement("span"); // span.style.visibility = "hidden"; // span.style.position = "absolute"; // span.style.top = "-9999px"; // span.style.whiteSpace = "nowrap"; // span.innerText = text; // document.body.appendChild(span); // const width = span.offsetWidth + 5; // document.body.removeChild(span); // return width; // } // ...其他方法 const emit = defineEmits([ "pagination", "update:currentPage", "update:pageSize", "selection-change", ]); const page = useVModel(props, "currentPage", emit); const size = useVModel(props, "pageSize", emit); function handleSizeChange(val: number) { emit("pagination", { currentPage: page, pageSize: val }); } function handleCurrentChange(val: number) { // console.log("val", val); page.value = val; emit("pagination", { currentPage: val, pageSize: props.pageSize }); } const handleSelectionChange = (val: any) => { emit("selection-change", val); }; const handleSelectable = (row: any) => { // console.log("row", row); return row.selectable; }; </script> <style lang="scss" scoped> .pagination { display: flex; justify-content: end; padding: 12px; margin-top: 5px; &.hidden { display: none; } } </style>
對于表格列寬實(shí)現(xiàn)了根據(jù)數(shù)據(jù)長度進(jìn)行每一列的展示:
/** * el-table擴(kuò)展工具 -- 列寬度自適應(yīng) * @param {*} prop 字段名稱(string) * @param {*} records table數(shù)據(jù)列表集(array) * @returns 列寬(int) */ export function getColumnWidth(label: string, prop: string, tableData: any) { //label表頭名稱 //prop對應(yīng)的內(nèi)容 //tableData表格數(shù)據(jù) const minWidth = 90; // 最小寬度 const padding = 10; // 列內(nèi)邊距 const arr = tableData.map((item: any) => item[prop]); arr.push(label); //拼接內(nèi)容和表頭數(shù)據(jù) const contentWidths = arr.map((item: any) => { // console.log("item", item); // console.log("PROP", prop); const value = item ? String(item) : ""; const textWidth = getTextWidth(value); return textWidth + padding; }); // console.log("contentWidths", contentWidths); let maxWidth = Math.max(...contentWidths); if (maxWidth > 240) { maxWidth = 240; } return Math.max(minWidth, maxWidth); } /** * el-table擴(kuò)展工具 -- 列寬度自適應(yīng) - 獲取列寬內(nèi)文本寬度 * @param {*} text 文本內(nèi)容 * @returns 文本寬度(int) */ function getTextWidth(text: string) { const span = document.createElement("span"); span.style.visibility = "hidden"; span.style.position = "absolute"; span.style.top = "-9999px"; span.style.whiteSpace = "nowrap"; span.innerText = text; document.body.appendChild(span); const width = span.offsetWidth + 5; document.body.removeChild(span); return width; }
到此這篇關(guān)于vue3基于elementplus 簡單實(shí)現(xiàn)表格二次封裝過程的文章就介紹到這了,更多相關(guān)vue表格二次封裝內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Vue實(shí)現(xiàn)選項(xiàng)卡tab切換制作
這篇文章主要為大家詳細(xì)介紹了Vue實(shí)現(xiàn)選項(xiàng)卡tab切換制作,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03vue實(shí)現(xiàn)列表無縫動(dòng)態(tài)滾動(dòng)
要想實(shí)現(xiàn)列表的動(dòng)態(tài)無縫滾動(dòng),本文為大家推薦兩款組件,vue-seamless-scroll和vue3-seamless-scroll,組件的用法也非常簡單,下面就跟隨小編一起來學(xué)習(xí)一下吧2024-11-11vue項(xiàng)目使用node連接數(shù)據(jù)庫的方法(前后端分離)
這篇文章主要介紹了vue項(xiàng)目使用node連接數(shù)據(jù)庫(前后端分離),本文結(jié)合示例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-12-12vue-cli項(xiàng)目根據(jù)線上環(huán)境分別打出測試包和生產(chǎn)包
這篇文章主要介紹了vue-cli項(xiàng)目根據(jù)線上環(huán)境打出測試包和生產(chǎn)包的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-05-05淺談Vue3 Composition API如何替換Vue Mixins
這篇文章主要介紹了淺談Vue3 Composition API如何替換Vue Mixins,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-04-04