基于element- plus 二次封装el-table


一般在后台管理系统的开发中,都会遇到很多table,但每一次都去引入el-table就会导致代码十分冗余,代码效率也会低下,所以基于组件做一下二次封装成自己需要的组件就十分nice。


拿element-plus官网举例:

<template>
  <div id="app">
     <el-table
      :data="tableData"
      style="width: 100%">
      <el-table-column
        prop="date"
        label="日期"
        width="180">
      </el-table-column>
      <el-table-column
        prop="name"
        label="姓名"
        width="180">
      </el-table-column>
      <el-table-column
        prop="address"
        label="地址">
      </el-table-column>
    </el-table>
  </div>
</template>

<script>
export default {
  name: 'App',
  components: {
  },
  setup () {
  const tableData = [{
            date: '2016-05-02',
            name: '王小虎',
            address: '上海市普陀区金沙江路 1518 弄'
          }, {
            date: '2016-05-04',
            name: '王小虎',
            address: '上海市普陀区金沙江路 1517 弄'
          }, {
            date: '2016-05-01',
            name: '王小虎',
            address: '上海市普陀区金沙江路 1519 弄'
          }, {
            date: '2016-05-03',
            name: '王小虎',
            address: '上海市普陀区金沙江路 1516 弄'
          }]
          return {
          tableData
          }
  }
}
</script>

<style lang="scss">

</style>
复制代码

这样一个简单的表格就好了,我们只需要在对应的el-table-column中加上对应的prop和label即可。

基于上面的表格定义一个公共组件,我命名为list- table。

image.png

然后在之前应用到的页面引入并使用

image.png

image.png

image.png

然后来到我们的list.vue逐个封装。首先要考虑我们table的数据类型有哪些,文本,图片,标签,日期,操作按钮等等。代码中我的数据绑定在dataSourc中,通过fieldType来识别字段类型。

selection选择框:

        <el-table-column
          v-if="dataSource.isSelection"
          :selectable="dataSource.selectable"
          type="selection"
          :width="dataSource.selectionWidth || 55">
        </el-table-column>
复制代码

序号

          <!-- 是否需要序号 -->
         <el-table-column
          v-if="dataSource.isIndex"
          type="index"
          label="序号"
          width="55">
        </el-table-column>
复制代码

图片字段

        <el-table-column
          :min-width="item.fieldType === 16 ? '50px' : '150px'"
          v-if="[7, 16].includes(item.fieldType)"
          :key="item.attr"
          :label="item.label">
          <template v-slot:header="scope">
            <el-tooltip :disabled="tableHeadTooltipShow" class="item" effect="dark" :content="scope.column.label" placement="top-start">
              <span class="table-head-label">
                <span @mouseenter="elementWidth">{{scope.column.label}}</span>
              </span>
            </el-tooltip>
          </template>
          <template v-slot="scope">
            <el-image class="list-table__table--header"
              :src="scope.row[item.attr]"
              alt=""
              :preview-src-list="[scope.row[item.attr]]">
              <template v-slot:error class="image-error-slot">
                <i class="el-icon-picture-outline"></i>
              </template>
            </el-image>
          </template>
        </el-table-column>
复制代码

日期

 <el-table-column
          v-else-if="[3, 13].includes(item.fieldType)"
          min-width="150px"
          :show-overflow-tooltip="true"
          :key="item.attr"
          :label="item.label">
          <template v-slot:header="scope">
            <el-tooltip :disabled="tableHeadTooltipShow" class="item" effect="dark" :content="scope.column.label" placement="top-start">
              <span class="table-head-label">
                <span @mouseenter="elementWidth">{{scope.column.label}}</span>
              </span>
            </el-tooltip>
          </template>
          <template v-slot="scope">
            {{formatDate(scope.row[item.attr], item.fieldType)}}
          </template>
        </el-table-column>
复制代码

以及日期格式化的方法,这里我引入了moment,感兴趣的可以了解一下

const formatDate = (val, fieldType) => {
      // 如果该时间为空,后端不返回该属性【val = undefined】,页面直接渲染空字符
      if (val === undefined) {
        return ''
      }
      if (val === 0) {
        return '永久有效'
      }
      if (String(val).length === 10) {
        val = val * 1000
      }
      const formatType = fieldType === 3 ? 'YYYY-MM-DD' : 'YYYY-MM-DD HH:mm:ss'
      return moment(val).format(formatType)
    }
复制代码

操作按钮

 <el-table-column
         v-else-if="item.fieldType === 99"
         width="150px"
         :key="item.attr"
         :label="item.label">
         <template v-slot:header="scope">
           <el-tooltip :disabled="tableHeadTooltipShow" class="item" effect="dark" :content="scope.column.label" placement="top-start">
             <span class="table-head-label">
               <span @mouseenter="elementWidth">{{scope.column.label}}</span>
             </span>
           </el-tooltip>
         </template>
         <template v-slot="scope">
           <span
             class="cloum-operation"
             v-for="(operation,index) in scope.row[item.attr]"
             :key="index"
             @click="operationRow(scope.row, operation.key)">
             {{operation.label}}
           </span>
         </template>
       </el-table-column>
复制代码

触发父组件中的方法

   const operationRow = (obj, operation) => {
      // console.log(obj)
      context.emit('operationRow', obj, operation)
    }
复制代码

其他一些文本信息

        <el-table-column
          v-else
          min-width="150px"
          :show-overflow-tooltip="true"
          :key="item.attr"
          :label="item.label">
          <template v-slot:header="scope">
            <el-tooltip :disabled="tableHeadTooltipShow" class="item" effect="dark" :content="scope.column.label" placement="top-start">
              <span class="table-head-label">
                <span @mouseenter="elementWidth">{{scope.column.label}}</span>
              </span>
            </el-tooltip>
          </template>
          <template v-slot="scope">
            <span @click="throughDetail(scope.row, item)" :class="{'can-through': item.detailThrough}">
              {{scope.row[item.attr]}}
            </span>
          </template>
        </el-table-column>
复制代码

以上也就封装好了一个简单的table,然后到应用到的页面在setup中定义一下静态数据

image.png

image.png

这样就算简单的封装成功了。

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享