vue3+ts+element-plus el-table组件二次封装(TTable组件新增columnSetBind属性(自定义设置按钮样式))

2023-07-17 TTable组件新增columnSetBind属性(自定义设置按钮样式),效果如下:

vue3+ts+element-plus el-table组件二次封装(TTable组件新增columnSetBind属性(自定义设置按钮样式))_第1张图片

一、需求

对于后台管理系统项目必不可少的列表数据渲染;而element-plus的table组件还是需要写很多代码;为了方便因此封装了TTable组件(一行代码,可以实现表格编辑/分页/表格内/外按钮操作/排序/显示隐藏表格内操作按钮)

二、组件功能

1、基础表格
2、带斑马线、带边框、固定列/表头
3、多级表头
4、自定义表头
5、单个单元格编辑功能
6、可以设置表格标题
7、可集成了分页组件
8、表格可以自定义插槽渲染某列数据
9、表格可以render渲染某列数据(支持jsx方式)
10、集成了表格内操作和表格外操作
11、支持某列字典过滤渲染
12、支持列--显示隐藏及拖拽排序
13、支持整行--拖拽排序
14、支持单元格编辑键盘事件(向上、向下、回车横向的下一个输入框)
15、表格实现了双击复制单元格内容功能
16、表格实现单选框选中取消功能

三、最终效果

四、参数配置

1、代码示例:

     <t-table
          :table="table"
          :columns="table.columns"
          @size-change="handlesSizeChange"
          @page-change="handlesCurrentChange"
        />

2、events 其他事件按照el-table直接使用(如sort-change排序事件)

事件名 说明 返回值
page-change 当前页码 当前选中的页码
save 保存按钮 编辑后的所有数据
handleEvent 单个输入触发事件 configEdit 中的 event 值和对应输入的 value 值
radioChange 单选选中事件 返回当前选中的整行数据
rowSort 行拖拽排序后触发事件 返回排序后的table数据

Methods 方法

事件名 说明 参数
clearSelection 用于多选表格,清空用户的选择 -
clearSort 清空排序条件 -
toggleRowSelection 取消某一项选中项 -
toggleAllSelection 全部选中 -

3、配置参数(Table Attributes)

参数 说明 类型 默认值
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组件二次封装

你可能感兴趣的:(element-plus,vue3,el-table,sortablejs,组件封装,二次封装,table)