ElementUI自定义Table支持render
ElementUI中的Table组件可以通过render-header属性通过render函数渲染表头,对于数据单元格并没有相关支持,虽然可以通过<template slot-scope="scope"></template >自定义列,但是在某些操作中直接用·render·形式进行渲染会更加有效,我一般喜欢通过数据的形式配置表格的内容,所以对ElementUI中的Table组件进行二次封装。
首先编写用于表头和数据单元格的部分:
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' } }) ] ) ]) }
以上为个人经验,希望能给大家一个参考,也希望大家多多支持阿兔在线工具。