前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Element Table 业务封装与思考

Element Table 业务封装与思考

作者头像
草帽lufei
发布2022-07-29 09:41:16
5270
发布2022-07-29 09:41:16
举报
文章被收录于专栏:程序语言交流

前言

新项目 Elemnet UI 组件业务封装,封装需求满足后期不修改业务代码,直接更新前端的封装组件的UI库代码即可实现无缝切换UI库的需求。目前新项目的功能产品还在梳理,项目第一期还未开始,前端技术小组先行进行的组件封装。

Table 组件封装目标

  • 封装的用法要和 Element UI Table 组件的用法保持一致
    • 目的是降低引用(使用)成本
  • 支持纯数据绑定
  • 支持自定义模板满足业务定制化需求

Table 组件封装内容

目录结构
代码语言:javascript
复制
components  封装组件目录
  talbe
    Index.vue
    TableColumn.vue
    
Views
  CenterPage.vue 组件调用层
table/Index.vue

这个文件默认封装了 el-table 组件外层,里面使用 v-bind="$attrs":xxx="config.xxx" 模式,在 el-table 内层使用 slot 来接受,这样可以满足表格的自定义模板需求,如果只是渲染基本数据,可以直接把 el-table-column 也封装好,如代码中的注释部分

代码语言:javascript
复制
<template>
  <div>
      <!-- v-model="config.value" -->
    <el-table
      v-bind="$attrs"
      :height="config.height"
      :max-height="config.maxHeight"
      :stripe="config.stripe"
      :border="config.border"
      :size="config.size"
      :fit="config.fit"
      :show-header="config.showHeader"
      :highlight-current-row="config.highlightCurrentRow"
      :row-class-name="config.rowClassName"
      :row-style="config.rowStyle"
      :cell-class-name="config.cellClassName"
      :cell-style="config.cellStyle"
      :header-row-class-name="config.headerRowClassName"
      :header-row-style="config.headerRowStyle"
      :header-cell-class-name="config.headerCellClassName"
      :header-cell-style="config.headerCellStyle"
      :row-key="config.rowKey"
      :empty-text="config.emptyText"
      :default-expand-all="config.defaultExpandAll"
      :expand-row-keys="config.expandRowKeys"
      :default-sort="config.defaultSort"
      :tooltip-effect="config.tooltipEffect"
      :show-summary="config.showSummary"
      :sum-text="config.sumText"
      :summary-method="config.summaryMethod"
      :span-method="config.spanMethod"
      :select-on-indeterminate="config.selectOnIndeterminate"
      :indent="config.indent"
      :lazy="config.lazy"
      :load="config.load"
      :tree-props="config.treeProps"
      v-on="$listeners"
    >
      <slot></slot>
      <!-- <template v-for="(v, i) in config.columns" >
        <el-table-column v-if="!v.slot" :key="i" :prop="v.prop" :label="v.label" :width="v.width">
        </el-table-column>
        <el-table-column v-else :key="i" :prop="v.prop" :label="v.label" :width="v.width">
          <slot></slot>
        </el-table-column>
      </template> -->
    </el-table>
  </div>
</template>

<script>
export default {
  name: 'Table',
  props: {
    content: {
      type: String,
      default: ''
    },
    config: {
      type: Object,
      default: () => { }
    }
  }
}
</script>
table/TableColumn.vue

这个文件封装的 el-table-column , 这里面同样了用了 slot 主要用于支持表格列中的自定义部分,添加了一个自定义的参数 isNativeRenter ,表示当前列配置是否是原生数据绑定渲染

代码语言:javascript
复制
<template>
  <!-- v-model="config.value" -->
  <el-table-column
    v-bind="$attrs"
    :type="config.type"
    :index="config.index"
    :column-key="config.columnKey"
    :label="config.label"
    :prop="config.prop"
    :width="config.width"
    :min-width="config.minWidth"
    :fixed="config.fixed"
    :render-header="config.renderHeader"
    :sortable="config.sortable"
    :sort-method="config.sortMethod"
    :sort-by="config.sortBy"
    :sort-orders="config.sortOrders"
    :resizable="config.resizeable"
    :formatter="config.formatter"
    :show-overflow-tooltip="config.showOverflowTooltip"
    :align="config.align"
    :header-align="config.headerAlign"
    :class-name="config.className"
    :label-class-name="config.labelClassName"
    :selectable="config.selectable"
    :reserve-selection="config.reserveSelection"
    :filters="config.filters"
    :filter-placement="config.filterPlacement"
    :filter-multiple="config.filterMultiple"
    :filter-method="config.filterMethod"
    :filtered-value="config.filteredValue"
    v-on="$listeners"
  >
    <template slot-scope="{ row, column, $index }">
      <slot :nativeData="[row, column, $index]" name="custom"></slot>
      <span v-if="!config.isNativeRenter">{{ row[column.property] }}</span>
    </template>
    <template slot="header">
      <slot name="header"></slot>
    </template>
  </el-table-column>
</template>

<script>
export default {
  name: 'TableColumn',
  props: {
    content: {
      type: String,
      default: ''
    },
    config: {
      type: Object,
      default: () => { }
    }
  }
}
</script>

注意

这里面的 <template><el-table-column> 的层级结构中间不能有任何其他元素,否则会影响表格列数据的正常排序。如下代码就不可取

代码语言:javascript
复制
<template>
  <div>
    <el-table-column></el-table-column>
  </div>
</template>
CenterPage.vue

基础表格调用,只渲染数据

template

代码语言:javascript
复制
<table :config="table.config" :data="table.data">
  <table-column :config="table.config.columns[0]"></table-column>
  <table-column :config="table.config.columns[1]"></table-column>
  <table-column :config="table.config.columns[2]"></table-column>
</table>

script

代码语言:javascript
复制
 table: {
    config: {
      columns: [
        {
          prop: 'date',
          label: '日期'
        },
        {
          prop: 'name',
          label: '姓名'
        },
        {
          prop: 'address',
          label: '地址'
          width: 300
        }
      ]
    },
    data: [{
      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 弄'
    }]
    },

自定义列模板表格

代码语言:javascript
复制
<c-table :config="table3.config" :data="table2.data">
  <table-column :config="table3.config.columns[0]">
    <template slot="custom" slot-scope="{ nativeData }">
      <span style="margin-left: 10px">{{ nativeData[2] }}</span>
    </template>
  </table-column>

  <table-column :config="table3.config.columns[1]">
    <template slot="custom" slot-scope="{ nativeData }">
      <i class="el-icon-time"></i>
      <span style="margin-left: 10px">{{ nativeData[0].date }}</span>
    </template>
  </table-column>
  <table-column :config="table3.config.columns[2]"></table-column>
  <table-column :config="table3.config.columns[3]"> </table-column>
  <table-column :config="table3.config.columns[4]">
    <template slot="custom" slot-scope="{ nativeData }">
      <el-button
        @click="handleSelectClick(nativeData)"
        type="primary"
        size="small"
        >查看</el-button
      >
      <el-button type="danger" size="small">删除</el-button>
    </template>
  </table-column>
</c-table>

数据层

代码语言:javascript
复制
table3: {
  config: {
    columns: [
      {
        width: '50',
        type: 'index'
      },
      {
        prop: 'date',
        label: '日期',
        width: '200',
        key: 'date',
        sortable: true,
        isNativeRenter: true
      },
      {
        prop: 'name',
        label: '姓名',
        key: 'name',
        sortable: true
      },
      {
        prop: 'address',
        label: '地址',
        width: '400',
        key: 'address'
      },
      {
        label: '操作',
        width: '200',
        fixed: 'right',
      }
    ],
    border: true,
    stripe: true,
    size: 'mini'
  },
  data: [{
    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 弄'
  }]
}

封装过程中遇到的问题和思考

  1. 整个封装过程使用到的技术点相关内容,主要为 slot 的合理使用父子组件的互相传值父子组件的事件触发
  2. 组件封装的内容在我们目前项目的高业务复杂度(包含高度自定义设计出来的功能,以及UI层的特殊需求效果)的项目中,当前业务未开展的情况下,无产品原型,无UI设计规范及效果,纯技术层封装对于业务的支持目前不确定,部分组件在开发过程使用可能需要二次调整和修改。
  3. 目前前端封装小组已经封装了一多半的 ElementUI 组件,一些组件在封装中发现,部分封装出来的组件在后期更换UI库时不时很灵活,在不调整业务代码的情况下,支持不同的UI库组件切换封装层的代码需要支持两种情况,或基于新的UI库组件用法修改调用参数进行匹配处理,这部分的后期在更新UI库时组件的修改代价还是很高的。

GitHub 源码地址

https://github.com/gywgithub/element2-package

GitHub 仓库预览地址

https://gywgithub.github.io/element2-package

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-04-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 参谋总长萨博 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • Table 组件封装目标
  • Table 组件封装内容
    • 目录结构
      • table/Index.vue
      • table/TableColumn.vue
      • CenterPage.vue
  • 封装过程中遇到的问题和思考
  • GitHub 源码地址
  • GitHub 仓库预览地址
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档