elementPlus表格二次封裝過程
為何要對(duì)element-plus表格進(jìn)行二次封裝?
- 我們正常在開發(fā)項(xiàng)目中,表格的風(fēng)格是一致的,但是表格或多或少會(huì)有些不同,有些是需要分頁,有些是按鈕功能不同,有些又需要加Tag,或者對(duì)時(shí)間進(jìn)行格式化等。所有才有了對(duì)element-plus的二次封裝。
優(yōu)勢(shì)
- 組件中集成表格、分頁、loading、tag等功能。
- 統(tǒng)一項(xiàng)目表格整體風(fēng)格。
- 快速將表格在分頁與不分頁間切換。
- 表格列可根據(jù)需求進(jìn)行定制化。
- 可快速開發(fā)大量自定義表格。
例子
<ELTable class="table" :table-data="tableObject.tableData" :columns="tableObject.columns" :page-config="tableObject.pageConfig" @current-change="onCurrentTableChange" > <template #operate="{ scope }"> <el-button size="small" @click="handleEdit(scope)">Edit</el-button> <el-button size="small" type="danger" @click="handleDelete(scope)" >Delete</el-button > </template> </ELTable>
參數(shù)
tableData 表格的數(shù)據(jù)
{ tableData: any[]; }
columns 列配置
type TableColumnType = { prop: string; label: string; attrs?: any; slot?: boolean; tagList?: TagObjectType[]; }; { columns: TableColumnType[]; };
pageConfig 頁面配置
type PageConfigType = { pageSize: number, total: number, pagerCount?: number, currentPage: number, // eslint-disable-next-line no-unused-vars handleCurrentChange: (val: number) => void }; { pageConfig: PageConfigType; }
currentChange 點(diǎn)擊分頁后的事件
{ currentPageChange: (val: number,oldVal: number) => void; }
整體簡單配置
<ELTable class="table" :table-data="tableObject.tableData" :columns="tableObject.columns" :page-config="tableObject.pageConfig" @current-change="onCurrentTableChange" > </ELTable> const tableObject = reactive<TableType>({ columns: [ { prop: 'date', label: 'Date', attrs: { width: 140 } }, { prop: 'alarm', label: '告警等級(jí)', attrs: { width: 100 } } ], pageConfig: { pageSize: 5, total: 100, pagerCount: 5, currentPage: 3, handleCurrentChange: (number: number) => { console.log('重新請(qǐng)求數(shù)據(jù)', number); } }, tableData: [ { date: '2016-05-03', alarm: '1' }, { date: '2016-05-02', alarm: '4' } ] });
簡單的例子
帶分頁表格
usePagination
添加 usePaginnation后即可實(shí)現(xiàn)表格分頁的功能,@current-change
是當(dāng)分頁頁面變化時(shí)的回調(diào)
<ELTable class="table" :table-data="tableObject.tableData" :columns="tableObject.columns" :page-config="tableObject.pageConfig" usePagination > </ELTable> const tableObject = reactive<TableType>({ columns: [], pageConfig: { pageSize: 5, total: 100, pagerCount: 5, currentPage: 3, // 當(dāng)前頁發(fā)生變化時(shí)的回調(diào) handleCurrentChange: (number: number) => { tableObject.pageConfig.currentPage = number; console.log('重新請(qǐng)求當(dāng)前頁的數(shù)據(jù)數(shù)據(jù)', number); } }, tableData: [] });
不帶分頁的表格
不帶分頁的表格只需要將 usePagination
設(shè)置為false,pageConfig項(xiàng)可以不設(shè)置即可
<ELTable class="table" :table-data="tableObject.tableData" :columns="tableObject.columns" :usePagination="false" > </ELTable> const tableObject = reactive<TableType>({ columns: [], tableData: [] });
帶 tag 的表格
<ELTable class="table" :table-data="tableObject.tableData" :columns="tableObject.columns" :page-config="tableObject.pageConfig" > </ELTable>
需要在 columns 下配置 tagList
import ELTable, { TableType } from '@/components/Table.vue'; const tableObject = reactive<TableType>({ columns: [ { prop: 'date', label: 'Date', attrs: { width: 140 } }, { prop: 'name', label: 'Name', attrs: { width: 80 } }, { prop: 'address', label: 'Address', attrs: { width: 180 } }, { prop: 'alarm', label: '告警等級(jí)', attrs: { width: 100 }, tagList: [ { label: '嚴(yán)重', value: '1', className: 'error' }, { label: '緊急', value: '2', className: 'warning' }, { label: '一般', value: '3', className: 'info' }, { label: '提示', value: '4', className: 'success' } ] } ], pageConfig: { pageSize: 5, total: 100, pagerCount: 5, currentPage: 3, handleCurrentChange: (number: number) => { console.log('重新請(qǐng)求數(shù)據(jù)', number); } }, tableData: [ { date: '2016-05-03', name: 'Tom', address: 'No. 189, Grove St, Los Angeles', alarm: '1' }, { date: '2016-05-02', name: 'Tom', address: 'No. 189, Grove St, Los Angeles', alarm: '4' }, { date: '2016-05-04', name: 'Tom44', address: 'No. 189, Grove St, Los Angeles', alarm: '3' }, { date: '2016-05-01', name: 'Tom55', address: 'No. 189, Grove St, Los Angeles', alarm: '1' }, { date: '2016-05-01', name: 'Tom55', address: 'No. 189, Grove St, Los Angeles', alarm: '1' } ] });
帶按鈕的表格
帶按鈕的表格一般是需要自定義模板的 。需要在 columns 下面的配置項(xiàng)中添加操作選項(xiàng)。然后插槽名則是 prop 的值。
<ELTable class="table" :table-data="tableObject.tableData" :columns="tableObject.columns" :page-config="tableObject.pageConfig" @current-change="onCurrentTableChange" > <template #operate="{ scope }"> <el-button size="small" @click="handleEdit(scope)">Edit</el-button> <el-button size="small" type="danger" @click="handleDelete(scope)" >Delete</el-button > </template> </ELTable>
import ELTable, { TableType } from '@/components/Table.vue'; const tableObject = reactive<TableType>({ columns: [ { prop: 'date', label: 'Date', attrs: { width: 140 } }, { prop: 'name', label: 'Name', attrs: { width: 80 } }, { prop: 'address', label: 'Address', attrs: { width: 180 } }, { prop: 'alarm', label: '告警等級(jí)', attrs: { width: 100 }, tagList: [ { label: '嚴(yán)重', value: '1', className: 'error' }, { label: '緊急', value: '2', className: 'warning' }, { label: '一般', value: '3', className: 'info' }, { label: '提示', value: '4', className: 'success' } ] }, { prop: 'operate', label: '操作', slot: true, attrs: { width: '180' } } ], pageConfig: { pageSize: 5, total: 100, pagerCount: 5, currentPage: 3, handleCurrentChange: (number: number) => { console.log('重新請(qǐng)求數(shù)據(jù)', number); } }, tableData: [ { date: '2016-05-03', name: 'Tom', address: 'No. 189, Grove St, Los Angeles', alarm: '1' }, { date: '2016-05-02', name: 'Tom', address: 'No. 189, Grove St, Los Angeles', alarm: '4' }, { date: '2016-05-04', name: 'Tom44', address: 'No. 189, Grove St, Los Angeles', alarm: '3' }, { date: '2016-05-01', name: 'Tom55', address: 'No. 189, Grove St, Los Angeles', alarm: '1' }, { date: '2016-05-01', name: 'Tom55', address: 'No. 189, Grove St, Los Angeles', alarm: '1' } ] });
配置插槽
如果在columns中配置了 sort:true。默認(rèn)就會(huì)讀取表格中插槽名稱為 props值的結(jié)構(gòu),放入當(dāng)前列。
<ELTable class="table" :table-data="tableObject.tableData" :columns="tableObject.columns" :page-config="tableObject.pageConfig" @current-change="onCurrentTableChange" > <template #aaa="{ scope }"> <el-button size="small" @click="handleEdit(scope)">Edit</el-button> <el-button size="small" type="danger" @click="handleDelete(scope)" >Delete</el-button > </template> </ELTable> <script> import ELTable, { TableType } from '@/components/Table.vue'; const tableObject = reactive<TableType>({ columns: [ { prop: 'aaa', label: '操作', attrs: { width: '180' }, slot: true // 屬性為true時(shí) 插槽生效,并讀取屬性名為 aaa 的插槽。 }, ], }); </script>
配置表格列的原生屬性
如果想要配置表格列的原生屬性。可以在clounms
下的 attrs
中去配置,例如:想要配置 fixed
、resizable
、formatter
等…
import ELTable, { TableType } from '@/components/Table.vue'; const tableObject = reactive<TableType>({ columns: [ { prop: 'date', label: 'Date', attrs: { // 配置表格的原生屬性 width: 140 fixed: true, resizable: true formatter: function(row,column) { console.log('過濾器') } } }, ], });
當(dāng)前項(xiàng)高亮?xí)r觸發(fā)的方法@selection-change
<ELTable class="table" :table-data="tableObject.tableData" :columns="tableObject.columns" :page-config="tableObject.pageConfig" @selection-change="onSelectionChange" highlight-current-row stripe > </ELTable> const onSelectionChange = (row) => { console.log('選中當(dāng)前項(xiàng)時(shí)會(huì)觸發(fā)的事件') }
table表格封裝的源碼
<template> <div class="cus-table"> <el-table v-loading="props.loading" :data="props.tableData" style="width: 100%" v-bind="$attrs"> <el-table-column v-for="column in props.columns" :key="column.prop" :prop="column.prop" :label="column.label" width="180" v-bind="column?.attrs"> <!-- 默認(rèn)有插槽的情況 --> <template #default="scope"> <slot v-if="column.slot" :name="column.prop" :scope="scope" /> <!-- 當(dāng)有告警時(shí)表格默認(rèn)做出處理 --> <template v-if="column.tagList?.length"> <div v-for="(tag, index) in filteredTagList(scope.row, column.tagList, column.prop)" :key="tag.value + '_' + index"> <div class="tag" :class="tag.className">{{ tag.label }}</div> </div> </template> </template> </el-table-column> </el-table> <!-- 分頁 --> <template v-if="props.usePagination"> <div class="pagination"> <div>總共 {{ pageConfig.total }} 條信息</div> <el-pagination v-model:current-page="currentPage" class="cus-pagination" background layout="prev, pager, next" :page-size="pageConfig.pageSize" :total="pageConfig.total" :pager-count="pageConfig.pagerCount" @current-change="pageConfig.handleCurrentChange" /> </div> </template> </div> </template> <script setup lang="ts"> type TagObjectType = { label: string; value: string; className: 'error' | 'warning' | 'info' | 'success' | 'offline'; }; type PageConfigType = { pageSize: number; total: number; pagerCount?: number; currentPage: number; // eslint-disable-next-line no-unused-vars handleCurrentChange?: (val: number) => void; }; type TableColumnType = { prop: string; label: string; attrs?: any; slot?: boolean; tagList?: TagObjectType[]; }; export type TableType = { tableData: any[]; columns: TableColumnType[]; pageConfig?: PageConfigType; loading?: boolean; usePagination?: boolean; }; const props = withDefaults(defineProps<TableType>(), { tableData: () => [], columns: () => [], pageConfig: () => ({ pageSize: 5, total: 0, currentPage: 1, }), loading: false, usePagination: true, }); const filteredTagList = (scope: any, tagList: any[], prop: string) => tagList?.filter((tag: any) => tag?.value === scope?.[prop]); const currentPage = ref(props.pageConfig.currentPage); </script> <style lang="scss" scoped> .error { background-color: rgba(171, 1, 0, 0.2); border: 2px solid rgba(255, 78, 77, 1); } .warning { background-color: rgba(185, 74, 0, 0.2); border: 2px solid rgba(255, 128, 15, 1); } .info { background-color: rgba(174, 127, 0, 0.2); border: 2px solid rgba(255, 235, 15, 1); } .tootip { background-color: rgba(0, 82, 183, 0.2); border: 2px solid rgba(61, 148, 255, 1); } .success { background-color: rgba(39, 191, 114, 0.2); border: 2px solid rgba(71, 221, 145, 1); } .offline { background-color: rgba(154, 158, 174, 0.2); border: 2px solid rgba(154, 158, 174, 1); } .cus-table { width: 100%; position: relative; overflow: hidden; .tag { display: flex; justify-content: center; align-items: center; width: 60px; height: 24px; color: #ffffff; opacity: 0.6; border-radius: 12px; } .pagination { display: flex; justify-content: space-between; align-items: center; margin-top: 30px; font-size: 18px; color: rgba(255, 255, 255, 0.6); } } </style>
到此這篇關(guān)于elementPlus表格二次封裝的文章就介紹到這了,更多相關(guān)elementPlus表格封裝內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue?目錄樹的展開與關(guān)閉的實(shí)現(xiàn)
Vue作為一款流行的前端框架,提供了一種數(shù)據(jù)驅(qū)動(dòng)的方式來實(shí)現(xiàn)目錄樹,本文主要介紹了vue?目錄樹的展開與關(guān)閉的實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的可以了解一下2023-11-11Vue POST請(qǐng)求頭'Content-Type':'application/j
這篇文章主要介紹了Vue POST請(qǐng)求頭'Content-Type':'application/json;',data上傳過程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-03-03vue中動(dòng)態(tài)設(shè)置meta標(biāo)簽和title標(biāo)簽的方法
這篇文章主要介紹了vue中動(dòng)態(tài)設(shè)置meta標(biāo)簽和title標(biāo)簽的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-07-07vue router動(dòng)態(tài)路由下讓每個(gè)子路由都是獨(dú)立組件的解決方案
這篇文章主要介紹了vue router動(dòng)態(tài)路由下讓每個(gè)子路由都是獨(dú)立組件的解決方案,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2018-04-04詳解Vue-cli3 項(xiàng)目在安卓低版本系統(tǒng)和IE上白屏問題解決
這篇文章主要介紹了Vue-cli3 項(xiàng)目在安卓低版本系統(tǒng)和 IE 上白屏問題解決,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2019-04-04