关于ElementUI自定义Table支持render

2022-10-21 10:30:10

目录ElementUI自定义Table支持renderElementUI-Table表头排序ElementUI自定义Table支持renderElementUI中的Table组件可以通过render-...

目录
ElementUI自定义Table支持render
ElementUI-Table表头排序

ElementUI自定义Table支持render

ElementUI中的Table组件可以通过render-header属性通过render函数渲染表头,对于数据单元格并没有相关支持,虽然可以通过<template slot-scope="scope"></template >自定义列,但是在某些操作中直接用·render·形式进行渲染会更加有效,我一般喜欢通过数据的形式配置表格的内容,所以对ElementUI中的Table组件进行二次封装。

首先编写用于表头和数据单PRlhAIAsvv元格的部分:

TableHeaderCell.js

export default {
 name: 'TableHeadCell',
 functional: true,
 props: {
  render: Function,
  index: Number,
  column: Object,
  scopeColumn: Object,
  columns: Array,
  data: Array
 },
 render: (h, ctx) => {
  if (typeof ctx.props.render === 'function') {
   const params = {
    index: ctx.props.index,
    column: ctx.props.column,
    scopeColumn: ctx.props.scopeColumn,
    columns: ctx.props.columns,
    data: ctx.props.data,
    _self: ctx
   }
   return ctx.props.render.call(ctx.parent.$parent, h, params)
  } else {
   return h('span', ctx.props.column.label || ctx.props.column.prop || ctx.props.scopeColumn.property)
  }
 }
}

TableCell.js

export default {
 name: 'TableCell',
 functional: true,
 props: {
  row: Object,
  render: Function,
  index: Number,
  column: Object,
  scopeColumn: Object,
  columns: Array,
  data: Array
 },
 render: (h, ctx) => {
  if (typeof ctx.props.render === 'function') {
   const params = {
    row: ctx.props.row,
    index: ctx.props.index,
    column: ctx.props.column,
    scopeColumn: ctx.props.scopeColumn,
    columns: ctx.props.columns,
    data: ctx.props.data,
    _self: ctx
   }
   return ctx.props.render.call(ctx.parent.$parent, h, params)
  } else {
   if (typeof ctx.props.column.formatter === 'function') {
    return h('span',
     ctx.props.column.formatter(
      ctx.props.row, ctx.props.scopeColumn,
      ctx.props.row[ctx.props.column.prop],
      ctx.props.index
     )
    )
   }
   return h('span', ctx.props.row[ctx.props.column.prop])
  }
 }
}

最后编写表格主要部分:index.vue

<template>
 <el-table
  ref="targetTable"
  :data="data"
  v-bind="$attrs"
  v-on="$listeners"
 >
  <slot slot="empty" name="empty" />
  <slot slot="append" name="append" />
  <slot name="columns">
   <el-table-column
    v-for="column in computedColumns"
    :key="column.prop"
    v-bind="column"
   >
    <template slot="header" slot-scope="scope">
     <tabel-head-cell :column="column" :scope-column="scope.column"
      :index="scope.$index" :render="column.headerRender" :columns="columns" :data="data" />
    </template>
    <template slot-scope="scope">
     <tabel-cell :row="scope.row" :column="column" :scope-column="scope.column"
      :index="scope.$index" :render="column.render" :columns="columns" :data="data" />
    </template>
   </el-table-column>
  </slot>
 </el-table>
</template>
<script>
import TabelCell from './TableCell'
import TabelHeadCell from './TableHeadCell'
const TATGET_TABLE_REF = 'targetTable'
export default {
 name: 'RenderTable',
 components: { TabelHeadCell, TabelCell },
 props: {
  columns: { type: Array, default: () => {} },
  data: { type: Array, default: () => {} }
 },
 computed: {
  computedColumns() {
   return this.columns && this.columns.filter(column => column.visible === undefined
    || column.visible === null || !!column.visible)
  }
 },
 methods: {
  // 表格原始方法
  clearSelection() {
   this.$refs[TATGET_TABLE_REF].clearSelection()
  },
  toggleRowSelection(row, selected) {
   this.$refs[TATGET_TABLE_REF].toggleRowSelection(row, selected)
  },
  toggleAllSelection() {
   this.$refs[TATGET_TABLE_REF].toggleAllSelection()
  },
  toggleRowExpansion(row, expanded) {
   this.$refs[TATGET_TABLE_REF].toggleRowExpansion(row, expanded)
  },
  setCurrentRow(row) {
   this.$refs[TATGET_TABLE_REF].setCurrentRow(row)
  },
  clearSort() {
   this.$refs[TATGET_TABLE_REF].clearSort()
  },
  clearFilter(columnKey) {
   this.$refs[TATGET_TABLE_REF].clearFilter(columnKey)
  },
  doLayout() {
   this.$refs[TATGET_TABLE_REF].doLayout()
  },
  sort(prop, order) {
   this.$refs[TATGET_TABLE_REF].sort(prop, order)
  }
 }
}
</script>

使用示例:

<template>
  <render-table
   :columns="columns"
   :data="list"
  />
</template>
<script>
import RenderTable from '_c/RenderTable'
export default {
 name: 'RenderTableTest',
 components: { RenderTable},
 data() {
  return {
   columns: [
    {
     prop: 'appId',
     label: '应用编号',
     fixed: true,
     align: 'center'
    },
    {
     prop: 'appName',
     label: '应用名称',
     align: 'center'
    },
    {
     prop: 'enabled',
     label: '是否启用',
     align: 'center',
     formatter(row, column, cellValue, index) {
      return cellValue ? '是' : '否'
     }
    },
    {
     fixed: 'right',
     label: '操作',
     align: 'center',
     render(h, { row }) {
      const _this = this
      return h('el-button-group', [
       h('el-button', {
        props: {
         size: 'mini',
         type: 'primary'
        },
        on: {
         'click'() {
          _this.handleEdit(row)
         }
        }
       }, '编辑')
      ])
     }
    }
   ],
   list: []
  }
 },
 methods: {
  handleEdit(row) {
  }
 }
}
</script>

ElementUI-Table表头排序

ElementUI-Table表头自带排序功能,和排序事件,但是目前只是对当前界面的数据进行排序。

项目需求:点击表头排序的时候,对所有数据进行排序。
初步方案:在点击排序按钮的时,在排序事件sort-change 中,进行数据请求,

此时会先重拍一次当前页面的数据,再渲染接口返回数据。用户体验不是很好。

优化方案:使用render-header自定义tableHeader,此时要使用render函数来创建表头。
getheaderTime(h) {
   const This = this
   return h('div', {
   },
    ['告警时间',
     h('span', {
      class: 'iline-table-sort'
     },
      [
       h('i', {
        'class': {
   编程      'el-icon-caret-bottom': This.orderByType === 'desc',
         'el-icon-caret-top': This.orderByType === 'asc',
         'active': This.orderBy === 'daqTime'
        },
        attrs: {
         'orderByType': 'desc',
         'orderType': 'daqTime'
        },
        on: {
         click: This.clickHandler
        },
        style: {
         fontSize: '22px'
        }
       })
      ]
     )
    ])
  }

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。