发布网友 发布时间:2022-04-21 02:10
共1个回答
热心网友 时间:2022-04-22 12:04
一、场景
在使用iview的时候发现表格和页码组件是分开的,我之前使用的UI组件库如easyUI和miniUI,它们的组件库是类似这样的:
只需要提供数据和数据总条数就可以渲染出表格+页码+描述,因此萌生了包装一个这样的表格组件;
必然会有考虑不周全或者可以优化的地方,在开发这一个月来陆陆续续修改了几次,目前看来可以满足大多数情况了~
先看一下实现的效果:
二、实现细节
1. 组件内定义的Table组件需要有所有iview表格属性和事件,属性Prop,事件emit回父组件;
2. 刷新表格的时机?
理所应当的,在翻页和修改每页条数大小时,这两种情况是必须要刷新数据的;
(1) 修改每页条数时,监听page组件的 on-page-size-change 事件:
这里设计的一个巧思是,on-page-size-change事件会触发翻页事件,将页码置为1,但是按照设想只需要刷新一次,因此需要在翻页事件触发之前先将页码置为1,然后在翻页事件中去判断页码是否一样;
// 修改每页显示的行数
changePageSize(pageSize) {
// 设置当前页码回第一页
this.current = 1;
this.pageSize = pageSize;
this.refresh();
}
(2) 翻页,监听翻页事件,on-change:
承接上面的解释,如果是由于on-page-size-change事件触发的翻页,此时pageIndex是1,再先前的changePageSize方法中已经先将页码置为1,因此判断如果相等,则不需要刷新,不等,则表示这是单纯的翻页事件,而不是由于on-page-size-change事件触发的;
changePage(pageIndex) {
if (this.current != pageIndex) {
this.current = pageIndex;
this.refresh();
} else {
console.log('这是由于每页显示条数事件触发的……');
}
}
3. 右下角的页码描述;
computed: {
sizeText: function() {
let end = this.current * this.pageSize;
end = end > this.total ? this.total : end;
return `当前${(this.current - 1) * this.pageSize + 1}~${end},共${this.total}条`;
}
}
4. iView表格组件的多选是通过设置column数组来定义的,封装组件的时候考虑到将多选作为一个布尔值进行设置,简化自定义代码;
props: {
showSelection: {
type: Boolean,
default: false
}
}
在生命周期created节点,根据父组件传递的 showSelection 给column动态加上多选框配置;
created() {
if (this.showSelection) {
this.columns.unshift({
width: 50, type: 'selection', align: 'center'
});
}
}
5. 表格的index也是每次使用时在column里面配置,也考虑到采用布尔值设置是否显示index,这里index的计算要结合页码和每页大小等信息来计算;
props: {
showIndex: {
type: Boolean,
default: false
}
}
与多选框类似的,在created钩子动态设置column;
created() {
if (this.showIndex) {
this.columns.unshift({
type: 'index',
width: 60,
align: 'center',
indexMethod: (row) => {
return this.pageSize * (this.current - 1) + row._index + 1;
},
// 原来是的序号表头会显示#,自定义成自己想要的文字显示
renderHeader: (h) => {
return h('span', '序号');
}
});
}
}
6. 关于单击控制复选框选中增加背景高亮;
iview的表格组件中单击某行并不能改变其复选框的选中与否,此外复选框选中之后该行的背景样式希望是高亮的,这样的话更加清晰明了,实现思路如下:
(1)根据iview表格组件文档,每行数据设置_checked属性的值,可以控制该行的复选框选中状态,因此单击事件可以通过设置_checked的值来达到控制复选框的目的;
onRowClick(row, index) {
// 设置数据行的check属性,触发表格选中
if (this.showSelection) {
this.tableData[index]._checked = !this.tableData[index]._checked;
}
// 设置目前选中的数据行数组
row._checked = !row._checked;
if (row._checked) {
// 选中的话直接加入
this.selects.push(row);
} else {
// 取消选中的话需要从已选中的列表中过滤出该行
let filters = this.selects.filter(item => item.id != row.id);
this.selects = filters;
}
this.$emit('on-row-click', row, index);
}
这里还附加实现了保存选中结果,即selects;
(2)复选框状态改变事件也需要设置_checked属性;
onSelectionChange(selection) {
this.selects = selection;
if (this.showSelection) {
// 根据选中的数据来设置整个表格每行数据的_checked属性
this.tableData.forEach((item) => {
let temp = selection.filter(item1 => item1.id == item.id);
if (temp && temp.length > 0) {
item._checked = true;
} else {
item._checked = false;
}
});
}
this.$emit('on-selection-change', selection);
},
(3)实现iview表格组件的row-class-name方法,根据每行的选中状态来调整背景颜色;
rowClassName(row) {
if (this.showSelection) {
if (row._checked) {
return 'table-selected-row';
}
return '';
} else {
return '';
}
}
<style>
.ivu-table .table-selected-row td{
background-color: #d5e3f1;
}
</style>
三、组件API
github: https://github.com/connie1992/iview-tables-chg
npm:https://www.npmjs.com/package/iview-tables-chg