案例 | iview中Table:拖拽适配列、自定义固定列、合并行

文 / 景朝霞
来源公号 / 朝霞的光影笔记
ID / zhaoxiajingjing

❥❥❥❥点个赞,让我知道你来过~❥❥❥❥


0 / 更新Table

"iview": "2.13.0",对比最新版本的iview:4.1.3中的Table功能,获取最新功能:拖拽、合并行等。

【PS:由于一些原因不能统一升级整个iview,我动了源码这很不好,望大佬们不吝赐教更好的方案~】

1 / Table的拖拽适配列

table.vue文件中handleResize方法里实现了:

不设置列的属性width,而是设置属性maxWidthminWidth用来适配在拖拽时表格产生的留白的适配,会把留白的宽度平均分配给适配列。

其中,最后呈现的宽度不会比最小宽还小,不会比最大宽度还大。

(1)拖拽设置边界值

为了使拖拽后的表格不会无限制的宽,也不会特别窄,设置边界值:

table.vue

minColumnWidth:{
    type:Number,
    default:50
},
maxColumnWidth:{
    type:Number,
    default:560
}

table-head.vue

const columnWidth = _width < this.minColumnWidth ? this.minColumnWidth : (_width > this.maxColumnWidth ? this.maxColumnWidth : _width);
(2)可拖拽范围加宽

把鼠标可拖拽的范围放宽:

if (rect.width > 12 && rect.right - event.pageX < 8) 
// 把判断条件的8改为16

table.less

.@{table-prefix-cls} {
    &-header{
        &-resizable{
            width: 20px; // 把原来的10px更新为20px
        }
    }
}

2 / Table的自定义固定列

公号ID:zhaoxiajiingjing

△图12.1:用户可以自己配置固定列

公号:朝霞的光影笔记

△图12.2:固定后的结果

【PS:实现此功能,请原谅我修改了源码】

在列上添加属性freezable:true表示允许用户自己设置固定列,其代码里面操作的依旧是列的属性fixed实现效果。

(1)新增泡泡文件freeze-poptip.vue


(2)在表头添加冻结提示泡泡table-head.vue

import FreezePoptip from './freeze-poptip.vue';


    

添加点击方法

// 2020年3月10日10:08:28 冻结
handleFreezable(index, type){
    const column = this.columns.find(item => item._index === index);
    const _index = column._index;
    this.$parent.handleFreezable(_index, type);
},
(3)修改table.vue
handleFreezable(_index, type){
    const index = this.GetOriginalIndex(_index);
    const key = this.cloneColumns[index].key;
    this.cloneColumns[index]._freezeVisiblePoptip = false;
    this.$emit('on-freeze-change', {
        column:JSON.parse(JSON.stringify(this.allColumns[this.cloneColumns[index]._index])),
        key,
        fixed:type
    });

},
 makeColumns (cols) {
     //....CODE
     let hasFreezable = columns.some(col => col.freezable===true);
     let hasResizable = columns.some(col => col.resizable===true);
     columns.forEach((column, index) => {
         //...CODE
         (hasFreezable || hasResizable ) && (column.width = parseInt(column.width));
         //...CODE
     });
     //....CODE
 }
(4)应用

应用的代码在文末

3 / Table的合并行

(1)阅读iview的源码

根据iview给出的例子,只需要把合并的规则传入到组件内即可

https://www.iviewui.com/components/table#H/LHB

公号ID:zhaoxiajingjing

△图12.3:iview的Table合并行的例子

table-body.vue在这里可以学习一下,如何判断一个方法的返回值是数组还是对象

getSpan (row, column, rowIndex, columnIndex) {
    // 拿到传过来的方法 spanMethod
    const fn = this.$parent.spanMethod;
    // 是function类型的才可以
    if (typeof fn === 'function') {
        // 调用该方法,并把返回值结果赋值给变量result
        const result = fn({
            row,
            column,
            rowIndex,
            columnIndex
        });
        // 设置初始值
        let rowspan = 1;
        let colspan = 1;
        if (Array.isArray(result)) { 
            // 返回结果值是数组
            rowspan = result[0];
            colspan = result[1];
        } else if (typeof result === 'object') {  
            // 返回结果值是对象
            rowspan = result.rowspan;
            colspan = result.colspan;
        }
        return {
            rowspan,
            colspan
        };
    } else { // 否则:{}
        return {};
    }
},

(1)判断是否为函数typeof fn === 'function'

(2)判断是否为数组Array.isArray(result)

(3)判断是否为对象typeof result === 'object'【仅限于此处约定的返回值是一个对象或者一个数组】

let fn = function (){
    return [];
};
if (typeof fn === 'function'){ // (1)
    const result = fn();
    if (Array.isArray(result)) { // (2)
        // ...something
    } else if (typeof result === 'object') { //(3)
        // ...something
    }
}

可以看到它的表格数据data5是一条一条写的。

对于我们想要的数据格式如下,那就需要处理一下了,具体方法见文末

[
    {
        "teacher":"教师1",
        "course":"语文",
        "studentList":[
            {
                "student":"学生1"
            },
            {
                "student":"学生2"
            }
        ]
    }
]
(2)鼠标移入的样式
公号:朝霞的光影笔记

△图12.4:鼠标移入的样式

思路:在设置合并行的时候,给一个统一的标识符,在鼠标移入后,把带有该标识符的都加上移入的样式

【PS:大佬们打脸轻一些,请不吝赐教更好的方案】

公号:朝霞的光影笔记

△图12.5:给tr加上行标识

rowClasses (_index) {
    // ...CODE
    let {rowspanHoverFlag} = objData;
    
    if(rowspanHoverFlag && objData){
        for (let rowIndex in this.objData) {
            let row = this.objData[rowIndex];
            if(row.rowspanHoverFlag === rowspanHoverFlag && this.$parent.$el) {
                let el = this.$parent.$el.querySelector(`.myhoverindex-${rowIndex}`);
    
                let _class = objData._isHover ?
                    ( `myhoverindex-${rowIndex} ${this.prefixCls}-row ${this.rowClsName(rowIndex)} ${this.prefixCls}-row-highlight ${this.prefixCls}-row-hover`)
                    : (`myhoverindex-${rowIndex} ${this.prefixCls}-row ${this.rowClsName(rowIndex)}`);
    
                (el!==null && el.setAttribute) && el.setAttribute('class',_class);
            }
        }
    }
    // ...CODE
}

4 / 应用

PS:自定义冻结是修改的源码,如需要该功能,请自行贴上面介绍的代码

PS:我动了源码这很不好,望大佬不吝赐教更好的方案

公号ID:zhaoxiajingjing

【你可能感兴趣】

  1. 题目 | let和var的区别(一、二)
  2. 图解 | let和var的区别(一、二)
  3. 题目 | 带VAR和不带VAR的区别
  4. 图解 | 带VAR和不带VAR的区别
  5. 总结 | LET和VAR区别(三、四)
  6. 图解 | 作用域和作用域链
  7. 练习题 | 作用域和作用域链
  8. 图解 | 理解闭包
  9. 案例 | 闭包作用:保护和保存


你可能感兴趣的:(案例 | iview中Table:拖拽适配列、自定义固定列、合并行)