这里通用表格,和上一篇通用表单一样的(表格组件都在我博客里),配置完全可控,然后每个el-table-column 都是通过传入的数组来循环便利渲染,大部分常用实现也写在了下面,无法具体实现或需要你自己自定义开发的,都可以通过render来开发。

想要jsx写法方式的可以看我另一篇博客

【TSX】vue3 + element-ui + tsx 通用表格组件

// 父组件中调用方式<CommonTableoverflowText:loading="loading":tableLabel="tableHeader":data="tableDatas":option="tableOption"@handleTableButton="handleTableButton"showRadioCheck@rowClick="rowClick"/>
// 配置参数export const pageInfo = {pageIndex: 1,totalCount: 4,pageSize: 10,
}
export const tableHeaderData = [{label: '部门名称/用户名称',prop: 'name',},{label: '部门负责人',prop: 'contactPerson',},
]export const tableOptionsData = {label: '操作',width: '300',fixed: 'right',children: [{hidden: false,label: '编辑',methods: 'edit',props: {type: 'text'}},{hidden: false,label: '批量用户',methods: 'settingUser',props: {type: 'text'}}]
}
<template><div v-loading="loading"><el-tableref="table"v-bind="{ ...props }":data="data"style="width: 100%":row-class-name="tabRowClassName"@select="handleSelectionChange":row-style="rowStyle"@select-all="handleSelectionChange":cell-class-name="cellClassName"header-row-class-name="custom-table-header":default-expand-all="expendAll"row-key="id":max-height="maxHeight"><!-- 单选框 --><el-table-columnv-if="showCheckBoX"width="55"type="selection":reserve-selection="keep":class-name="turnRadio ? `checkBoxRadio` : ``"align="center"></el-table-column><!-- 序号 --><el-table-column v-if="showTypeIndex" align="center" label="序号" width="50"><template #default="{ $index }">{{ $index + 1 }}</template></el-table-column><!-- 表格 --><el-table-columnv-for="item in tableLabel.filter((item) => item.label)":width="item.width ? item.width : ''":key="item[keyId]":align="!!item.align ? item.align : 'center'":label="item.label":show-overflow-tooltip="overflowText":fixed="item.fixed":prop="item.prop"><template #default="{ row }"><template v-if="item.Image"><div><el-image class="table-img" :src="row.attachment" :preview-src-list="[row.attachment]"><template #error><span>无</span></template></el-image></div></template><!--进度条--><template v-else-if="item.progress"><el-progress class="progress-line" :text-inside="true" :stroke-width="26" :percentage="row[item.prop]"></el-progress></template><template v-else-if="item.render"><div style="cursor: pointer" @click="!!item.methods && handleClickon(item.methods, row)" v-html="item.render(row)"></div></template><template v-else-if="item.isTag"><el-tag :class="'el-tag--' + item.formatTag(row[item.prop] / 1)">{{ item.format(row[item.prop] / 1) }}</el-tag></template><!-- 自定义标签 --><template v-else-if="item.customTag"><el-tag :class="'el-tag--' + getCustomTagName(item.customTagName, row)">{{ row[item.prop] }}</el-tag></template><template v-else-if="item.format"><div v-if="typeof item.format === 'function'">{{ item.format(row[item.prop], row, item) }}</div></template><template v-else><div class="text-no-wrap" @click="!!item.methods && handleClickon(item.methods, row)">{{ Object.prototype.toString.call(item.prop) == '[object Array]' ? propFilter(item.prop, row) : row[item.prop] }}</div></template></template></el-table-column><el-table-column v-if="!!option" :width="option.width" :label="option.label" :fixed="option.fixed" align="center"><template #default="scope" v-if="!!option.children"><!-- 常规正常情况 --><el-buttontype="text"v-for="(item, index) in option.children":key="index"v-show="!buttonHidden(item, scope.row)"v-bind="{ ...item.props }":disabled="buttonDisabled(item, scope.row)"@click="handleTableButton(item.methods, scope.row, index, scope.$index)":class="['btn-' + item.methods, 'btn-right']"size="mini"><template v-if="item.render"><div v-html="item.render(scope.row)"></div></template>{{ !!item.label ? item.label : '' }}</el-button></template></el-table-column></el-table><Paginationv-show="pageInfo.totalCount > 0":total="pageInfo.totalCount":page="pageInfo.pageIndex":limit="pageInfo.pageSize":pageSizes="pageInfo.pageArr"@pagination="getList"/></div>
</template><script lang="ts">import { defineComponent, computed, PropType, ref, onMounted, nextTick, reactive, watch } from 'vue'import { useStore } from 'store/index'import { Utils } from '@/utils'import { isNumber } from '@/utils/is'interface PageInfo {pageIndex: numbertotalCount: numberpageSize: numberpageArr?: [][ket: string]: any}interface ColumnI {label: stringprop: stringwidth?: string | number}interface TableOption {label: stringmethods: stringprops: objectstyle: objectrender: Function}interface TableOptions {label: stringwidth: string | numberfixed: booleanpopoverWidth?: number | stringchildren: Array<TableOption>}interface Props {maxHeight: string | numberstateArr: Array<any>tableLabel: Array<ColumnI>option: TableOptionshowCheckBoX: booleanshowTypeIndex: booleanturnRadio: booleanselectedIdArr: Array<any>pageInfo: PageInfoshowPagination: booleanoverflowText: booleanloading: booleankeep: booleankeyId: stringdata: Array<any>expendAll: boolean}export default defineComponent({name: 'CommonTable',props: {maxHeight: {type: [String, Number],default: 600},stateArr: {type: Array,default: () => {return []}},tableLabel: {// 表格展示type: Array as PropType<Array<ColumnI>>,default: () => {return []}},data: {// 数据源type: Array as PropType<Array<any>>,default: () => {return []}},option: {// 配置需要显示的操作菜单type: Object as PropType<TableOption>},showCheckBoX: {// 配置是否显示全选(复选框)type: Boolean,default: false},showTypeIndex: {type: Boolean,default: false},turnRadio: {type: Boolean,default: false},selectedIdArr: {type: Array,default: []},pageInfo: {// 配置分页type: Object,default: () => {return {pageIndex: 1,totalCount: 0,pageSize: 10,pageArr: []}}},showPagination: {// 是否隐藏 分页显示type: Boolean,default: true},overflowText: {// 是否 隐藏文字过长type: Boolean,default: false},loading: {// loading 配置type: Boolean,default: false},keep: {type: Boolean,default: false},keyId: {// 动态绑定 key 值type: String,default: 'id'},props: {// 表格参数配置type: Object,default: function () {return {'show-header': true, // 显示表头e'highlight-current-row': false, // 是否要高亮当前行'tooltip-effect': 'dark', //'max-height': 'auto', // Table 的最大高度。合法的值为数字或者单位为 px 的高度。'empty-text': '没有数据', // 空数据显示状态'element-loading-text': '加载中', // loading 加载'header-cell-style': {background: '#F2F4F7',color: '#333',fontSize: '13px'}, // 表头样式border: false, // 是否带有纵向边框fit: true, // 列的宽度是否自撑开stripe: false // 是否显示斑马纹}}},rowStyle: {type: Object,default: () => {return {height: '40px'}}},expendAll: {type: Boolean,default: false}},setup(props: any, { emit }) {watch(() => props.data,() => {if (props.showCheckBoX || props.turnRadio) {nextTick(() => {table.value.clearSelection()curPageCheck.value = []if (props.showCheckBoX && props.turnRadio) {props.data.filter((item: any) => {if (item.id == props.selectedIdArr[0]) {table.value.toggleRowSelection(item, true)}})} else if (props.showCheckBoX) {props.data.filter((item: any) => {if (props.selectedIdArr.includes(item.id)) {table.value.toggleRowSelection(item, true)curPageCheck.value.push(item.id)}})}})}},{deep: true,immediate: true})watch(() => props.selectedIdArr,(val) => {console.log('hello now', val)if (props.showCheckBoX || props.turnRadio) {nextTick(() => {table.value.clearSelection()curPageCheck.value = []if (props.showCheckBoX && props.turnRadio) {props.data.filter((item: any) => {if (item.id == val[0]) {table.value.toggleRowSelection(item, true)}})} else if (props.showCheckBoX) {props.data.filter((item: any) => {if (val.includes(item.id)) {table.value.toggleRowSelection(item, true)curPageCheck.value.push(item.id)}})}})}},{deep: true})const getCustomTagName = (e: any, row: any): string => {let customTagName = ''if (Object.prototype.toString.call(e) === '[object Function]') {customTagName = e(row)} else {customTagName = e}return customTagName}/*** prop 单值 或者 数组过滤(此处为针对时间组,不作为通用处理)*/const propFilter = (prop: [Array<any> | object], row: any) => {let res = prop.reduce((total: string, cur: any) => {if (row[cur]) {return (total += row[cur] + '~')} else {return ''}}, '')// console.log(res)return res ? res.replace(/~$/, '') : ''}const handleTableButton = (methods: any, row: object, index: number, rowIndex: number) => {// 按钮事件emit('handleTableButton', { methods, row, index, rowIndex })}const handleClickon = (methods: any, row: object) => {if (typeof methods !== 'string') throw '方法名错误'// 数据操作emit(methods, { methods, row })}const curPageCheck = ref<Array<any>>([])const handleSelectionChange = (val: Array<any>) => {console.log(val, 12345)let arr = val.map((item) => parseInt(item.id))console.log('空', curPageCheck.value)let compare = Utils.compareArray(curPageCheck.value, arr)if (props.showCheckBoX && props.turnRadio) {// 选择项大于1时if (val.length > 1) {let del_row = val.shift()table.value.toggleRowSelection(del_row, false)}}// 全选if (props.showCheckBoX && props.selectedIdArr) {if (props.turnRadio) {emit('handleSelectionChange', val)} else {emit('handleSelectionChange', val, compare)}} else {emit('handleSelectionChange', val)}}const getList = (pages: any) => {let { page, limit } = pagesif (!isNumber(page)) {page = page.value}if (!isNumber(limit)) {limit = limit.value}const pageInfo = {page,limit}emit('handleGetList', pageInfo)}const getRowKeys = (row: any) => {return row.id}const table = ref<any>(null)const selectAll = (val: any) => {if (props.showCheckBoX && props.turnRadio) {// 选择项大于1时if (val.length > 1) {val.length = 1}}emit('handleSelectionChange', val)}//斑马纹表格背景色const tabRowClassName = ({ row, rowIndex }: any) => {let index = rowIndex + 1if (index % 2 == 0) {return 'even-row'} else {return 'odd-row'}return ''}const cellClassName = ({ row, column, rowIndex, columnIndex }: any) => {if (row.confirmTag === 2 && columnIndex < (props as any).tableLabel.length) {return 'height_light_cell'} else {return ''}}const buttonHidden = (item: any, row?: any) => {if (typeof item.hidden === 'function') return item.hidden(row) || falseif (!item.hidden) return item.hidden}const buttonDisabled = (item: any, row?: any) => {if (typeof item.disabled === 'function') return item.disabled(row) || falseif (!item.disabled) return item.disabled}const store = useStore()const buttonType = computed(() => store.state.app.buttonType)const showVertical = ref<boolean>(false)/*** 单选框选中事件*/const rowClick = (row: any): void => {emit('rowClick', row)}const radioId = ref<number | string>(-1)return {propFilter,handleTableButton,handleClickon,handleSelectionChange,getList,getRowKeys,tabRowClassName,cellClassName,buttonHidden,buttonDisabled,buttonType,showVertical,table,radioId,rowClick,getCustomTagName,selectAll}}})
</script><style lang="scss" scoped>@import '@/styles/index.scss';::v-deep .el-table__header,::v-deep .el-table__body {margin: 0;}.scrollBar {@include scrollBar;}::v-deep .el-table::before {height: 0;}::v-deep .el-button {padding: 0;border: none;margin: 0 4px;padding: 0 4px 0 8px;border-left: 1px solid #e2e2e2;font-size: 14px;min-height: 14px;&:first-child {border-left: none;}}::v-deep .el-button + .el-button {margin-left: 0;}.btn-see {color: #39a6ff;}.btn-handel {color: #41a4bd;}.btn-edit {color: #fcb0fb;}.btn-delete,.btn-del {color: #fd9090;}.btn-revoke {color: #ffa913;}::v-deep .btn-right div {margin-right: 5px;}.btn-right div:empty {margin-right: 0px;}//斑马纹表格背景色::v-deep(.el-table) .even-row {--el-table-tr-background-color: #f5fafb;}::v-deep(.el-table) .odd-row {--el-table-tr-background-color: #ffffff;}.el-table--border::after,.el-table--group::after {width: 0;}::v-deep .el-table td,th.is-leaf {border: none;}::v-deep .el-table__fixed-right::before,.el-table__fixed::before {background-color: transparent;}::v-deep .custom-table-header {th {background-color: #62c4ee !important;color: #fff !important;}}.progress-line {.el-progress-bar__outer {height: 16px !important;}.el-progress-bar__outer,.el-progress-bar__inner {border-radius: 0 !important;}}.text-no-wrap {@include text-no-wrap;cursor: pointer;display: inline;}::v-deep(.el-table) {td.el-table__cell div,th.el-table__cell > .cell {font-size: 14px;}th.el-table__cell > .cell {font-weight: normal;}.cell {padding: 0 10px;line-height: 39px;}.el-table__header-wrapper .checkBoxRadio .el-checkbox {display: none;}.el-checkbox {display: flex;align-items: center;justify-content: center;}.table-img {width: 60px;height: 60px;object-fit: cover;padding: 6px 0;display: flex;align-items: center;margin: 0 auto;justify-content: center;}}::v-deep(.el-table--small .el-table__cell) {padding: 0;}::v-deep(.el-dropdown-menu__item) {padding: 0 !important;.el-button {width: 100%;text-align: center;padding: 0 8px;margin: 0;}}
</style>

【template写法】TS + vue3.2 + vite2 + element-plus 通用表格组件封装相关推荐

  1. Element Plus 虚拟化表格组件的使用(排序、筛选、自定义单元格渲染) - 个人使用总结

    前言 element-plus@2.2.0 后提供虚拟化表格组件,解决表格数据过大导致的卡顿等性能问题.相对于表格组件,用法上区别还是挺大的,尤其是一些附加的功能,例如排序.筛选.自定义单元格/表头渲 ...

  2. 解决element的Table表格组件的高度问题( height只能是数字或者字符串 ),实现height: calc(100vh - 260px) 的效果

    注:也可直接将el-table的height属性绑定为字符串:calc(100vh - 260px) 实现为同样的效果, 260 是顶部和底部导航以及部分自定义布局 :例: <template& ...

  3. Element el-table 等表格组件超出隐藏(show-overflow-tooltip)按需展示且可鼠标移入

    实际需求中往往会有表格中超出列宽则 - 隐藏,并且显示 popover/tooltip 的场景. 虽然最新的 Element Table 提供了 show-overflow-tooltip 属性可以很 ...

  4. VUE : 双重 for 循环写法、table 解析任意 list 、万能表格组件、解析一维数组、动态生成 table 所有数据

    前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家.点击跳转到教程. 1.需求: 我想要一个 table 组件能在实际调用时动态生成所有的  tr .td . 后端返回的 ...

  5. Element Plus 跟踪表格数据总数,包括查询、筛选等操作

    前言 Element Plus的表格组件提供了筛选功能 前端项目中,如果表格使用的是后端分页,使用表格插件及分页器插件就可以了.这种情况下,前端的表格筛选被后端的分页条件查询取代了 另一种情况:不分页 ...

  6. element 表格+分页封装

    原因:element ui 的表格组件默认是不带分页的功能,但是实际工作中表格总是搭配分页功能一起出现的.封装在一起使用方便不需要每次都复制粘贴一大堆. 可以根据自己的需求更改,自己根据设计图定义样式 ...

  7. element ui设置表格表头高度和每一行的高度

    填坑记录:今天用element ui的表格组件做用户信息展示,直接拉取的官网的代码过来,发现表头和每一行都太高了,如下: 因为第一次使用element ui的表格组件,不太清楚会遇到这样的坑,以为能轻 ...

  8. 使用Vite创建Vue3+TS项目并整合Element Plus框架等一条龙服务

    记录一下使用Vite创建Vue3+TS项目以及整合Element Plus框架,还有Less.Pinia.Vue-router.monaco-editor等插件或组件. 一.使用Vite创建Vue3+ ...

  9. Vue3 - Element plus 实现 “带分页“ 表格组件,实现跨页进行 “分页勾选“ 的多选功能(解决分页表格组件 <el-table> 跨页后已前勾选的行自动消失问题)详细示例解决教程

    前言 在 Vue3 项目中,使用 Element Plus 组件库的表格组件时,出现了跨页勾选复选框消失的问题. 本文实现了 vue3 中 element plus 表格组件 <el-table ...

最新文章

  1. pip install 及导出安装库,批量安装库
  2. Zend Guard6.0使用教程——PHP代码加密
  3. [转载]项目风险管理七种武器-多情环
  4. 简单配置jena在eclipse的开发环境
  5. JSTL标签显示分页
  6. vant 下拉框样式_使用 Vue 的 Vant.js List 列表组件实现无限下拉
  7. IS环境下配置PHP5+MySql+PHPMyAdmin
  8. 北大青鸟java y2_Struts-2 北大青鸟 Y2学年 项目案例使用 2框架开发租房网站 Java Develop 249万源代码下载- www.pudn.com...
  9. vc2017 linux printf,C/C++中自定义信息输出——printf与宏的配合使用
  10. [Yarn] Yarn local-dirs are bad 导致节点处于不健康状态
  11. 接口测试时,输入所有参数的参数值后,接口返回“参数错误:所有参数都不能为空”
  12. 201542010208、201571030331软件工程结对项目
  13. 【气温预测】基于matlab BP神经网络气温预测【含Matlab源码 714期】
  14. Wonderware Intouch 2014R2 SP1授权教程
  15. 多维奇异谱分析(Multivariate Singular Spectrum Analysis,MSSA)
  16. JQuery中$.ajax()方法参数详解
  17. Mac终端神器iTerm2配置(oh-my-zsh+shell integration+Powerlevel9k)
  18. 计算机如何调成音乐,如何调出适用于我的均衡器设置?
  19. 某程序员因准点下班没加班,被劝退!网友:还有没有天理?
  20. JavaCV开发详解之3:通用拉流器实现,从流媒体服务器拉流rtsp/rtmp录制成视频文件

热门文章

  1. 视频教程-mybatis快速入门到精通-Java
  2. 腐烂国度的计算机学知识,腐烂国度2手工艺知识
  3. .html页面如何加入c标签,C标签如何使用
  4. 拍摄的视频数据丢失怎么办,如何恢复摄像机误删的视频
  5. pycharm——运行项目Error: Please select a valid Python interpreter
  6. 论如何让女孩子喜欢你。
  7. 旋转接头的原理和优势以及安装方法
  8. 【C++ Primer Plus】第9章 内存模型和名称空间
  9. 55 人见人爱A-B
  10. JS实现下拉选择日期,下拉选择年月日