Table组件 jb-table
jb-table
组件是在VxeTable
基础上扩展的,所以VxeTable
中支持的属性在jb-table
中都可以使用。另外也封装了 jb-column
,用法同 VxeColumn
jb-table
做了以下扩展:
- 提供了一些默认配置
- 全局格式化内容
- 配合JBolt后端,提供了默认的表头指定列的按序查询功能
- 提供了拖拽排序功能
默认配置
border
:true
默认显示边框height
:true
默认高度自适应showHeaderOverflow
:tooltip
默认开启:表头内容过长时显示为省略号并显示tooltipshowOverflow
:tooltip
默认开启:单元格内容过长时显示为省略号并显示tooltipalign
:center
默认列内容居中对齐row-config
:{isHover: true,isCurrent: true,keyField: 'id',useKey: true}
默认开启行的hover
和点击高亮,使用id
字段作为行的key
,并为每一行设置key属性column-config
:{resizable: true}
默认开启列宽调整功能sortConfig
:{remote:true}
默认开启后端按序查询功能,并提供了默认的按序查询逻辑。- 将
seqConfig
中的startIndex
属性提取为组件的prop,方便配置。
基于以上配置,当我们使用<jb-table></jb-table>
时,就相当于以下代码:
vue
<vxe-table align="center" :border="true" height="auto"
showHeaderOverflow="tooltip" showOverflow="tooltip"
:row-config="{isHover: true,isCurrent: true,keyField: 'id',useKey: true}"
:column-config="{resizable: true}"
:sort-config="{remote:true}"
>
</vxe-table>
<vxe-table align="center" :border="true" height="auto"
showHeaderOverflow="tooltip" showOverflow="tooltip"
:row-config="{isHover: true,isCurrent: true,keyField: 'id',useKey: true}"
:column-config="{resizable: true}"
:sort-config="{remote:true}"
>
</vxe-table>
全局格式化内容
使用 formats 添加格式函数,单元格会在渲染的时候自动调用
(用于实现业务中统一的格式化处理,这对于很多场景非常有用,减少很多不必要的重复代码)
ts
import { VXETable } from 'vxe-table'
import XEUtils from 'xe-utils'
// 格式化日期,默认 yyyy-MM-dd
VXETable.formats.add('date', {
cellFormatMethod ({ cellValue }, format) {
return XEUtils.toDateString(cellValue, format || 'yyyy-MM-dd')
}
})
// 四舍五入金额,每隔3位逗号分隔,默认2位数
VXETable.formats.add('amount', {
cellFormatMethod ({ cellValue }, digits = 2) {
return XEUtils.commafy(XEUtils.toNumber(cellValue), { digits })
}
})
// 格式化银行卡,默认每4位空格隔开
VXETable.formats.add('bankcard', {
cellFormatMethod ({ cellValue }) {
return XEUtils.commafy(XEUtils.toValueString(cellValue), { spaceNumber: 4, separator: ' ' })
}
})
// 向下舍入,默认两位数
VXETable.formats.add('cutNumber', {
cellFormatMethod ({ cellValue }, digits = 2) {
return XEUtils.toFixed(XEUtils.floor(cellValue, digits), digits)
}
})
// 四舍五入,默认两位数
VXETable.formats.add('fixedNumber', {
cellFormatMethod ({ cellValue }, digits = 2) {
return XEUtils.toFixed(XEUtils.round(cellValue, digits), digits)
}
})
// 格式化性别
VXETable.formats.add('sex', {
cellFormatMethod ({ cellValue }) {
return cellValue ? (cellValue === '1' ? '男' : '女') : ''
}
})
import { VXETable } from 'vxe-table'
import XEUtils from 'xe-utils'
// 格式化日期,默认 yyyy-MM-dd
VXETable.formats.add('date', {
cellFormatMethod ({ cellValue }, format) {
return XEUtils.toDateString(cellValue, format || 'yyyy-MM-dd')
}
})
// 四舍五入金额,每隔3位逗号分隔,默认2位数
VXETable.formats.add('amount', {
cellFormatMethod ({ cellValue }, digits = 2) {
return XEUtils.commafy(XEUtils.toNumber(cellValue), { digits })
}
})
// 格式化银行卡,默认每4位空格隔开
VXETable.formats.add('bankcard', {
cellFormatMethod ({ cellValue }) {
return XEUtils.commafy(XEUtils.toValueString(cellValue), { spaceNumber: 4, separator: ' ' })
}
})
// 向下舍入,默认两位数
VXETable.formats.add('cutNumber', {
cellFormatMethod ({ cellValue }, digits = 2) {
return XEUtils.toFixed(XEUtils.floor(cellValue, digits), digits)
}
})
// 四舍五入,默认两位数
VXETable.formats.add('fixedNumber', {
cellFormatMethod ({ cellValue }, digits = 2) {
return XEUtils.toFixed(XEUtils.round(cellValue, digits), digits)
}
})
// 格式化性别
VXETable.formats.add('sex', {
cellFormatMethod ({ cellValue }) {
return cellValue ? (cellValue === '1' ? '男' : '女') : ''
}
})
示例代码:
vue
<jb-table :data="list">
...
<jb-column field="createTime" title="日期" min-width="180" formatter="date"></jb-column>
<jb-column field="money" title="金额" min-width="120" formatter="amount"></jb-column>
<jb-column field="bankcard" title="银行卡" min-width="180" formatter="bankcard"></jb-column>
<jb-column field="cutNumber" title="截取2位数" min-width="160" formatter="cutNumber"></jb-column>
<jb-column field="fixedNumber" title="四舍五入2位数" min-width="160" formatter="fixedNumber"></jb-column>
<jb-column field="sex" title="格式化性别" width="100" formatter="sex"></jb-column>
...
</jb-table>
<jb-table :data="list">
...
<jb-column field="createTime" title="日期" min-width="180" formatter="date"></jb-column>
<jb-column field="money" title="金额" min-width="120" formatter="amount"></jb-column>
<jb-column field="bankcard" title="银行卡" min-width="180" formatter="bankcard"></jb-column>
<jb-column field="cutNumber" title="截取2位数" min-width="160" formatter="cutNumber"></jb-column>
<jb-column field="fixedNumber" title="四舍五入2位数" min-width="160" formatter="fixedNumber"></jb-column>
<jb-column field="sex" title="格式化性别" width="100" formatter="sex"></jb-column>
...
</jb-table>
默认的按序查询功能
前提条件:
jb-table
需要在jb-crud-page
下声明,jb-table
的数据来源于jb-curd-page
提供的list。参考这里jb-crud-page
需要声明search-url
属性- 后端对应
search-url
的接口需要支持根据sortType
和sortColumn
两个参数排序查询 - 支持按序查询的列组件要声明
sortable
属性和field
属性
当jb-table
下的jb-column
声明了sortable
属性时,就会开启该列的按序查询功能。 示例代码:
vue
<jb-crud-page
search-url="/api/admin/demoTable/datas"
:search-conditions="pageConditions"
>
<template #default="{ list }">
<jb-table :data="list">
...
<jb-column field="age" title="年龄" width="100" sortable></jb-column>
...
</jb-table>
</template>
</jb-crud-page>
<jb-crud-page
search-url="/api/admin/demoTable/datas"
:search-conditions="pageConditions"
>
<template #default="{ list }">
<jb-table :data="list">
...
<jb-column field="age" title="年龄" width="100" sortable></jb-column>
...
</jb-table>
</template>
</jb-crud-page>
当点击排序按钮时,会自动调用jb-crud-page
的查询功能。此时jb-crud-page
会向search-url
地址发起get请求,请求参数除了jb-crud-page
组件上声明的search-conditions
,还会额外附加sortType
和sortColumn
两个参数,后端需要根据这两个参数进行排序查询返回数据。
参数 | 值 | 说明 |
---|---|---|
sortType | asc 、desc 、null | 排序类型,asc升序、desc降序、null取消排序 |
sortColumn | 排序按钮所在列声明的field 属性值 | 根据哪一个属性排序 |
拖拽排序功能
拖拽排序功能基于 vue-draggable-plus 第三方拖拽排序组件实现。目前使用上有以下限制:
- 不支持空节点嵌入。比如有一个树形table,里面有一个节点a,a下面的子节点是空的,此时如果想把一个节点b拖拽到a下面成为a的子节点,是不支持的。
- 不支持有固定列的table。因为固定列会通过渲染多个table实现,但拖拽只能在一个table上监听,导致拖拽时样式混乱、错位等问题发生。因此一旦开启拖拽,
jb-table
会强制取消列的固定,保证样式正常(需要配合jb-column
使用)。
开启拖拽排序需要的属性声明
属性 | 值 | 说明 |
---|---|---|
dragable | boolean | 是否开启排序。一旦为true,会强制取消列的固定。 |
rankField | string | 数据中代表顺序的字段名 |
rowConfig.keyField | string,默认值id | 数据的唯一性标识字段名 |
treeConfig.childrenField | string | 如果是树表,要声明包含子节点的字段名,例如children 或者items |
onDragEnd | (data:DragEndEventArgs):void | Promise<void> | 拖拽后的回调 |
示例
vue
<jb-table
ref="tableRef"
:tree-config="{
showLine: true,
childrenField: 'items',
reserve: true,
expandAll: true,
rowField: 'id'
}"
:data="data"
:dragable="true"
rank-field="sortRank"
@drag-end="handleDragEnd"
>
</jb-table>
<jb-table
ref="tableRef"
:tree-config="{
showLine: true,
childrenField: 'items',
reserve: true,
expandAll: true,
rowField: 'id'
}"
:data="data"
:dragable="true"
rank-field="sortRank"
@drag-end="handleDragEnd"
>
</jb-table>
ts
function handleDragEnd(data: DragEndEventArgs) {
return JBoltApi.post('/api/admin/permission/changeSortRank', {
id: data.id,
oriPid: data.oriPid,
oriRank: data.oriRank,
newPid: data.newPid,
newRank: data.newRank
}).then(() => {
return pageRef.value?.loadData()
})
}
function handleDragEnd(data: DragEndEventArgs) {
return JBoltApi.post('/api/admin/permission/changeSortRank', {
id: data.id,
oriPid: data.oriPid,
oriRank: data.oriRank,
newPid: data.newPid,
newRank: data.newRank
}).then(() => {
return pageRef.value?.loadData()
})
}
说明
- 拖拽后,
jb-table
会保持拖拽状态,但不会真的更改数据属性值。所以应该在onDragEnd
回调函数中,将拖拽后的数据提交到后端,后端处理完成后,再重新加载最新数据。 - 拖拽后,
jb-table
会一直loading,阻止用户二次操作,直到onDragEnd
回调函数执行完成。 onDragEnd
回调函数参数说明:
参数名 | 说明 |
---|---|
id | 被拖拽的节点id,它的值根据 rowConfig中配置的keyField字段 获取 |
item | 被拖拽节点的完整数据 |
oriPid | 原父节点id值,非树形结构时为0 |
oriParentItem | 原父节点完整数据,非树形结构时为null |
newPid | 新父节点id值,非树形结构时为0 |
newParentItem | 新父节点完整数据,非树形结构时为null |
beforeItem | 拖拽完成后前一个元素的完整数据,null代表拖拽到最前面 |
oriRank | 拖拽前的顺序,它的值根据 rankField 字段获取 |
newRank | 拖拽后的顺序,它的值根据 rankField 字段获取 |