新接手的一个项目 是基于ant-design-vue admin的开发,当需求要实现类似elementUI的合计行效果时,发现提供的API不支持,然后写了这个组件,也当练基础了
思路要点有
- 创建与父表格同样结构的table并渲染合计行数据
- 考虑到很多表格有滚动条,因此监听父组件的滚动事件,同步滚动子组件
- 隐藏子组件的滚动条
- 因为父组件的footer slot 自带一部分样式,因此为了保持父子组件宽度表现一致,需要针对清除
以下是实现代码
组件部分
<template>
<s-table
ref="summaryTable"
:size="config.size"
:columns="config.columns"
:scroll="config.scroll"
:data="loadData"
:showHeader="false"
:showPagination="false"
>
<span slot="serial" slot-scope="text, record, index">
{{ config.summaryText }}
</span>
</s-table>
</template>
<script>
import { STable, Ellipsis } from '@/components'
export default {
name: 'STableSummary',
props: {
data: {
type: Object,
default: () => {}
},
columns: {
type: Array,
default: () => []
},
summaryMethod: {
type: Function
},
props: {
type: Object,
default: () => {}
}
},
data() {
return {}
},
watch: {
data(val) {
this.$refs.summaryTable.refresh()
}
},
mounted() {
this.listenScroll()
this.setFooterStyle()
},
computed: {
config() {
return {
columns: [],
size: 'middle',
columns: 'columns',
scroll: '{ x: 1300 }',
summaryText: '合计',
...this.props
}
}
},
methods: {
async loadData() {
let data = { ...this.data }
if (this.summaryMethod) {
const list = this.summaryMethod(this.columns, this.data.list)
data = { ...data, list }
}
return data
},
listenScroll() {
let parentDom = this.$parent.$el.querySelectorAll('.ant-table-body')[0]
parentDom.addEventListener(
'scroll',
() => {
this.$refs.summaryTable &&
this.$refs.summaryTable.$el &&
(this.$refs.summaryTable.$el.querySelectorAll('.ant-table-body')[0].scrollLeft = parentDom.scrollLeft)
},
true
)
},
setFooterStyle() {
let $footer = this.$parent.$el.querySelectorAll('.ant-table-footer')[0]
if ($footer) {
$footer.style = 'padding:0;border:none;'
}
}
},
components: {
STable,
Ellipsis
}
}
</script>
<style lang="less" scoped>
/deep/ .ant-table-scroll .ant-table-body {
overflow: hidden !important;
}
</style>
父组件调用
<s-table
ref="table"
size="middle"
:columns="columns"
:data="loadData"
bordered
showPagination="auto"
:scroll="{ x: 1300 }"
>
<span slot="serial" slot-scope="text, record, index">
{{ record.serial }}
</span>
<span slot="footer" slot-scope="text">
<STableSummary :data="summaryData" :props="{ columns, scroll: { x: 1300 } }" />
</span>
</s-table>
另外,在实现过程中发现:showHeader="false"这个属性在s-table中不起作用,查看源码发现是props传递的时候出了问题
将s-table组件 render方法中
this[k]&& (props[k] = this[k])
改为
this[k] !== undefined && (props[k] = this[k])
后解决问题