2023-07-17 TTable组件新增columnSetBind属性(自定义设置按钮样式),效果如下:
对于后台管理系统项目必不可少的列表数据渲染;而element-plus的table组件还是需要写很多代码;为了方便因此封装了TTable组件(一行代码,可以实现表格编辑/分页/表格内/外按钮操作/排序/显示隐藏表格内操作按钮)
1、基础表格
2、带斑马线、带边框、固定列/表头
3、多级表头
4、自定义表头
5、单个单元格编辑功能
6、可以设置表格标题
7、可集成了分页组件
8、表格可以自定义插槽渲染某列数据
9、表格可以render渲染某列数据(支持jsx方式)
10、集成了表格内操作和表格外操作
11、支持某列字典过滤渲染
12、支持列--显示隐藏及拖拽排序
13、支持整行--拖拽排序
14、支持单元格编辑键盘事件(向上、向下、回车横向的下一个输入框)
15、表格实现了双击复制单元格内容功能
16、表格实现单选框选中取消功能
<t-table
:table="table"
:columns="table.columns"
@size-change="handlesSizeChange"
@page-change="handlesCurrentChange"
/>
事件名 | 说明 | 返回值 |
---|---|---|
page-change | 当前页码 | 当前选中的页码 |
save | 保存按钮 | 编辑后的所有数据 |
handleEvent | 单个输入触发事件 | configEdit 中的 event 值和对应输入的 value 值 |
radioChange | 单选选中事件 | 返回当前选中的整行数据 |
rowSort | 行拖拽排序后触发事件 | 返回排序后的table数据 |
事件名 | 说明 | 参数 |
---|---|---|
clearSelection | 用于多选表格,清空用户的选择 | - |
clearSort | 清空排序条件 | - |
toggleRowSelection | 取消某一项选中项 | - |
toggleAllSelection | 全部选中 | - |
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
table | 表格数据对象 | Object | {} |
—data | 展示数据 | Array | [] |
—toolbar | 表格外操作栏选中表格某行,可以将其数据传出 | Array | [] |
—operator | 表格内操作栏数据 | Array | [] |
-------show | 表格内操作栏根据状态显示 | Object | - |
-------noshow | 表格内操作栏根据多种状态不显示 | Array | - |
—operatorConfig | 表格内操作栏样式 | Object | - |
—firstColumn | 表格首列(序号 index,复选框 selection)排列 | object | - |
—total | 数据总条数 | Number | - |
—pageSize | 页数量 | Number | - |
—currentPage | 是否需要显示切换页条数 | Number | - |
columns | 表头信息 | Array | [] |
----sort | 排序 (设置:sort:true) | Boolean | false |
----renderHeader | 列标题 Label 区域渲染使用的 Function(val) 可以用 jsx 方式 | Function | - |
----bind | el-table-column Attributes | Object | - |
----noShowTip | 是否换行 (设置:noShowTip:true) | Boolean | false |
----slotName | 插槽显示此列数据(其值是具名作用域插槽 | String | - |
----slotNameMerge | 合并表头插槽显示此列数据(其值是具名作用域插槽) | String | - |
----------scope | 具名插槽获取此行数据必须用解构接收{scope}.row 是当前行数据 } | Object | - |
----canEdit | 是否开启单元格编辑功能 | Boolean | false |
----configEdit | 表格编辑配置(开启编辑功能有效) | Object | - |
----------label | placeholder 显示 | String | - |
----------editComponent | 组件名称可直接指定全局注册的组件,也可引入’element/abtd’如:‘a-input/el-input’ | String | - |
----------eventHandle | 第三方 UI 的 事件(返回两个参数,第一个自己自带,第二个 scope) | Object | - |
----------bind | 第三方 UI 的 Attributes,如 el-input 中的 clearable 清空功能 | Object | - |
----------event | 触发 handleEvent 事件的标志 | String | - |
----------type | 下拉或者复选框显示(select-arr/select-obj/checkbox) | String | - |
----------list | 下拉选择数据源名称 | String | - |
----------arrLabel | type:select-arr 时对应显示的中文字段 | String | - |
----------arrKey | type:select-arr 时对应显示的数字字段 | String | - |
----filters | 字典过滤 | Object | - |
----------list | listTypeInfo 里面对应的下拉数据源命名 | String | - |
----------key | 数据源的 key 字段 | String | ‘value’ |
----------label | 数据源的 label 字段 | String | ‘label’ |
listTypeInfo | 下拉选择数据源 | Object | - |
footer | 底部操作区(默认隐藏,使用插槽展示“保存”按钮) | slot | - |
isKeyup | 单元格编辑是否开启键盘事件 | Boolean | false |
isShowFooterBtn | 是否显示保存按钮 | Boolean | false |
title | 表格左上标题 | String /slot | - |
isShowPagination | 是否显示分页(默认显示分页) | Boolean | true |
isTableColumnHidden | 是否开启合计行隐藏复选框/单选框 | Boolean | false |
isCopy | 是否允许双击单元格复制 | Boolean | false |
rowClickRadio | 是否开启点击整行选中单选框 | Boolean | true |
columnSetting | 是否显示设置(隐藏/显示列) | Boolean | false |
name | 与 columnSetting 配合使用标记隐藏/显示列唯一性 | String | title |
isRowSort | 是否开启行拖拽(row-key 需要设置) |
Boolean | false |
columnSetBind | 列设置按钮配置(继承el-button 所有属性) |
Object | - |
----btnTxt | 按钮显示文字 | String | ‘列设置’ |
----title | 点击按钮下拉显示title | String | ‘列设置’ |
----size | el-button的size | String | ‘default’ |
----icon | el-button的icon | String | ‘Setting’ |
<template>
<div class="t-table">
<div class="header_wrap">
<div class="header_title">
{{title}}
<slot name="title" />
div>
<div class="toolbar_top">
<slot name="toolbar">slot>
<div class="header_right_wrap" :style="{marginLeft:isShow('toolbar')?'12px':0}">
<slot name="btn" />
<column-set v-if="columnSetting" v-bind="$attrs" :columns="columns"
@columnSetting="v => state.columnSet = v" />
div>
div>
div>
<el-table ref="TTable" :data="state.tableData" :class="{'highlightCurrentRow':highlightCurrentRow}" v-bind="$attrs"
size="default" :highlight-current-row="highlightCurrentRow" :border="table.border"
:cell-class-name="cellClassNameFuc">
<el-table-column v-if="table.firstColumn.type==='selection'" :type="table.firstColumn.type"
:width="table.firstColumn.width||55" :reserve-selection="table.firstColumn.isPaging||false"
:label="table.firstColumn.label" :align="table.firstColumn.align||'center'" :fixed="table.firstColumn.fixed"
v-bind="$attrs">el-table-column>
<el-table-column :type="table.firstColumn.type" :width="table.firstColumn.width||55"
:label="table.firstColumn.label||'序列'" :fixed="table.firstColumn.fixed"
:align="table.firstColumn.align||'center'" v-if="table.firstColumn.type==='index'" v-bind="$attrs">
<template #default="scope">
<span>{{isShowPagination?((table.currentPage - 1) * table.pageSize + scope.$index + 1):scope.$index +
1}}span>
template>
el-table-column>
<template v-for="(item,index) in renderColumns">
<template v-if="!item.children">
<el-table-column v-if="item.isShowCol===false?item.isShowCol:true" :key="index+'i'" :type="item.type"
:label="item.label" :prop="item.prop" :min-width="item['min-width'] || item.minWidth || item.width"
:sortable="item.sort||sortable" :align="item.align || 'center'" :fixed="item.fixed"
:show-overflow-tooltip="item.noShowTip===false?item.noShowTip:true" v-bind="{...item.bind,...$attrs}">
<template #header v-if="item.renderHeader">
<render-header :column="item" :render="item.renderHeader" />
template>
<template #default="scope">
<template v-if="item.render">
<render-col :column="item" :row="scope.row" :render="item.render" :index="scope.$index" />
template>
<template v-if="item.slotName">
<slot :name="item.slotName" :scope="scope">slot>
template>
<template v-if="item.canEdit">
<single-edit-cell :canEdit="item.canEdit" :configEdit="item.configEdit"
v-model="scope.row[scope.column.property]" :prop="item.prop" :record="scope"
@handleEvent="handleEvent" v-bind="$attrs" ref="editCell">
<slot v-if="item.configEdit&&item.configEdit.editSlotName" :name="item.configEdit.editSlotName"
:scope="scope" />
single-edit-cell>
template>
<div v-if="!item.render&&!item.slotName&&!item.canEdit">
<span>{{scope.row[item.prop]}}span>
div>
template>
el-table-column>
template>
<t-table-column v-else :key="index+'m'" :item="item" />
template>
<slot>slot>
<el-table-column v-if="table.operator" :fixed="table.operatorConfig && table.operatorConfig.fixed"
:label="(table.operatorConfig && table.operatorConfig.label) || '操作'"
:min-width="(table.operatorConfig && (table.operatorConfig.width || table.operatorConfig.minWidth)) || 100"
:align="table.operatorConfig && table.operatorConfig.align||'center'" class-name="operator">
<template #default="scope">
<div class="operator_btn" :style="table.operatorConfig && table.operatorConfig.style">
<el-button v-for="(item, index) in table.operator" :key="index"
@click="item.fun&&item.fun(scope.row,scope.$index,state.tableData)" :type="item.type" text
:style="item.style" :icon="item.icon?item.icon:''" :disabled="item.disabled" size="small"
v-show="checkIsShow(scope,item)">
<template v-if="item.render">
<render-col :column="item" :row="scope.row" :render="item.render" :index="scope.$index" />
template>
<span v-if="!item.render">{{item.text}}span>
el-button>
div>
template>
el-table-column>
el-table>
<el-pagination v-show="(state.tableData && state.tableData.length) && isShowPagination" small
:current-page="table.currentPage" @current-change="handlesCurrentChange" :page-sizes="[10, 20, 50, 100]"
:page-size="table.pageSize" layout="total, prev, pager, next, jumper" :total="table.total" v-bind="$attrs"
background>
el-pagination>
<footer class="handle_wrap" v-if="isShowFooterBtn&&(state.tableData&&state.tableData.length>0)">
<slot name="footer" />
<div v-if="!$slots.footer">
<el-button type="primary" @click="save">保存el-button>
div>
footer>
div>
template>
gitHub组件地址
gitee码云组件地址
vue3+ts基于Element-plus再次封装基础组件文档
基于ElementUi再次封装基础组件文档
vue+element-ui的table组件二次封装