案例 | iview中Table:拖拽適配列叁执、自定義固定列茄厘、合并行

文 / 景朝霞
來(lái)源公號(hào) / 朝霞的光影筆記
ID / zhaoxiajingjing

????點(diǎn)個(gè)贊,讓我知道你來(lái)過(guò)~????


0 / 更新Table

"iview": "2.13.0",對(duì)比最新版本的iview:4.1.3中的Table功能谈宛,獲取最新功能:拖拽次哈、合并行等。

【PS:由于一些原因不能統(tǒng)一升級(jí)整個(gè)iview吆录,我動(dòng)了源碼這很不好窑滞,望大佬們不吝賜教更好的方案~】

1 / Table的拖拽適配列

table.vue文件中handleResize方法里實(shí)現(xiàn)了:

不設(shè)置列的屬性width,而是設(shè)置屬性maxWidthminWidth用來(lái)適配在拖拽時(shí)表格產(chǎn)生的留白的適配恢筝,會(huì)把留白的寬度平均分配給適配列哀卫。

其中,最后呈現(xiàn)的寬度不會(huì)比最小寬還小撬槽,不會(huì)比最大寬度還大此改。

(1)拖拽設(shè)置邊界值

為了使拖拽后的表格不會(huì)無(wú)限制的寬,也不會(huì)特別窄侄柔,設(shè)置邊界值:

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)可拖拽范圍加寬

把鼠標(biāo)可拖拽的范圍放寬:

if (rect.width > 12 && rect.right - event.pageX < 8) 
// 把判斷條件的8改為16

table.less

.@{table-prefix-cls} {
    &-header{
        &-resizable{
            width: 20px; // 把原來(lái)的10px更新為20px
        }
    }
}

2 / Table的自定義固定列

公號(hào)ID:zhaoxiajiingjing

△圖12.1:用戶(hù)可以自己配置固定列

公號(hào):朝霞的光影筆記

△圖12.2:固定后的結(jié)果

【PS:實(shí)現(xiàn)此功能共啃,請(qǐng)?jiān)徫倚薷牧嗽创a】

在列上添加屬性freezable:true表示允許用戶(hù)自己設(shè)置固定列,其代碼里面操作的依舊是列的屬性fixed實(shí)現(xiàn)效果暂题。

(1)新增泡泡文件freeze-poptip.vue
<template>
    <!-- 2020年3月10日10:01:50 可以?xún)鼋Y(jié) -->
    <Poptip
            v-model="showFlag"
            popper-class="ivu-table-popper "
            trigger="hover"
            placement="top" :transfer="true">
        <span :class="[prefixCls + '-freeze']">
            <Icon type="loudou" ></Icon>
        </span>
        <div slot="content" :class="[prefixCls + '-freeze-list']">
            <slot name="freezeContent"></slot>
        </div>
    </Poptip>
</template>
<script>
    import Poptip from '../poptip/poptip.vue';

    export default {
        components: { Poptip },
        props:{
            prefixCls: String,
            show:{
                type:Boolean
            },
            hide:{
                type:Boolean
            }
        },
        watch:{
            hide(newFlag, oldFlag){
                if(newFlag === false) {
                    this.showFlag = false;
                }
            }
        },
        data() {
            return {
                showFlag:this.show
            };
        }
    }
</script>
(2)在表頭添加凍結(jié)提示泡泡table-head.vue

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

<FreezePoptip v-if="column.freezable"
    :show="getColumn(rowIndex, index)._freezeVisible"
              :prefixCls="prefixCls"
              :hide="getColumn(rowIndex, index)._freezeVisiblePoptip"
>
    <template slot="freezeContent">
        <ul :class="[prefixCls + '-freeze-list-single']">
            <li :class="[prefixCls + '-filter-select-item']"
                @click="handleFreezable(getColumn(rowIndex, index)._index, 'left')">
                <Button type="text" :class="[prefixCls + '-freeze-btn']"
                          :disabled="column.fixed === 'left'" >左側(cè)凍結(jié)</Button>
            </li>
            <li :class="[prefixCls + '-filter-select-item']"
                @click="handleFreezable(getColumn(rowIndex, index)._index, 'right')">
                <Button type="text" :class="[prefixCls + '-freeze-btn']"
                          :disabled="column.fixed === 'right'">右側(cè)凍結(jié)</Button>
            </li>
            <li :class="[prefixCls + '-filter-select-item']"
                @click="handleFreezable(getColumn(rowIndex, index)._index, '')">
                <Button type="text" :class="[prefixCls + '-freeze-btn']"
                          :disabled="(typeof column.fixed === 'string' && column.fixed.length === 0) || typeof column.fixed === 'undefined'" >還原</Button>
            </li>
        </ul>
    </template>
</FreezePoptip>

添加點(diǎn)擊方法

// 2020年3月10日10:08:28 凍結(jié)
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)應(yīng)用

應(yīng)用的代碼在文末

3 / Table的合并行

(1)閱讀iview的源碼

根據(jù)iview給出的例子移剪,只需要把合并的規(guī)則傳入到組件內(nèi)即可

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

公號(hào)ID:zhaoxiajingjing

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

table-body.vue在這里可以學(xué)習(xí)一下,如何判斷一個(gè)方法的返回值是數(shù)組還是對(duì)象

getSpan (row, column, rowIndex, columnIndex) {
    // 拿到傳過(guò)來(lái)的方法 spanMethod
    const fn = this.$parent.spanMethod;
    // 是function類(lèi)型的才可以
    if (typeof fn === 'function') {
        // 調(diào)用該方法薪者,并把返回值結(jié)果賦值給變量result
        const result = fn({
            row,
            column,
            rowIndex,
            columnIndex
        });
        // 設(shè)置初始值
        let rowspan = 1;
        let colspan = 1;
        if (Array.isArray(result)) { 
            // 返回結(jié)果值是數(shù)組
            rowspan = result[0];
            colspan = result[1];
        } else if (typeof result === 'object') {  
            // 返回結(jié)果值是對(duì)象
            rowspan = result.rowspan;
            colspan = result.colspan;
        }
        return {
            rowspan,
            colspan
        };
    } else { // 否則:{}
        return {};
    }
},

(1)判斷是否為函數(shù)typeof fn === 'function'

(2)判斷是否為數(shù)組Array.isArray(result)

(3)判斷是否為對(duì)象typeof result === 'object'【僅限于此處約定的返回值是一個(gè)對(duì)象或者一個(gè)數(shù)組】

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
    }
}

可以看到它的表格數(shù)據(jù)data5是一條一條寫(xiě)的纵苛。

對(duì)于我們想要的數(shù)據(jù)格式如下,那就需要處理一下了言津,具體方法見(jiàn)文末

[
    {
        "teacher":"教師1",
        "course":"語(yǔ)文",
        "studentList":[
            {
                "student":"學(xué)生1"
            },
            {
                "student":"學(xué)生2"
            }
        ]
    }
]
(2)鼠標(biāo)移入的樣式
公號(hào):朝霞的光影筆記

△圖12.4:鼠標(biāo)移入的樣式

思路:在設(shè)置合并行的時(shí)候攻人,給一個(gè)統(tǒng)一的標(biāo)識(shí)符,在鼠標(biāo)移入后悬槽,把帶有該標(biāo)識(shí)符的都加上移入的樣式

【PS:大佬們打臉輕一些贝椿,請(qǐng)不吝賜教更好的方案】

公號(hào):朝霞的光影筆記

△圖12.5:給tr加上行標(biāo)識(shí)

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 / 應(yīng)用

PS:自定義凍結(jié)是修改的源碼,如需要該功能陷谱,請(qǐng)自行貼上面介紹的代碼

PS:我動(dòng)了源碼這很不好,望大佬不吝賜教更好的方案

公號(hào)ID:zhaoxiajingjing

【你可能感興趣】

  1. 題目 | let和var的區(qū)別(一、二)
  2. 圖解 | let和var的區(qū)別(一烟逊、二)
  3. 題目 | 帶VAR和不帶VAR的區(qū)別
  4. 圖解 | 帶VAR和不帶VAR的區(qū)別
  5. 總結(jié) | LET和VAR區(qū)別(三渣窜、四)
  6. 圖解 | 作用域和作用域鏈
  7. 練習(xí)題 | 作用域和作用域鏈
  8. 圖解 | 理解閉包
  9. 案例 | 閉包作用:保護(hù)和保存
<template>
    <Table
                border
                ref="selection"
                :columns="columns3"
                :data="data3"
                :span-method="handleSpan"
                @on-freeze-change="onFreezeChange"

        ></Table>
</template>
<script>

    export default {

        data() {
            return {
                columns3:[
                    {
                        title:'教師',
                        key:'teacher',
                        resizable:true,
                        freezable:true,
                        width:100
                    },
                    {
                        title:'教師編號(hào)',
                        key:'teacherCode',
                        resizable:true,
                        freezable:true,
                        width:120
                    },
                    {
                        title:'課程',
                        key:'course',
                        resizable:true,
                        freezable:true,
                        width:120
                    },
                    {
                        title:'學(xué)生',
                        key:'student',
                        rowRelation:'many',
                        resizable:true,
                        freezable:true,
                        width:100
                    },
                    {
                        title:'學(xué)號(hào)',
                        key:'studentCode',
                        rowRelation:'many',
                        resizable:true,
                        width:120
                    },
                    {
                        title:'成績(jī)',
                        key:'score',
                        rowRelation:'many',
                        resizable:true,
                        freezable:true,
                        width:100
                    },
                    {
                        title:'批語(yǔ)',
                        key:'explain',
                        rowRelation:'many',
                        freezable:true,
                        minWidth:100
                    }
                ],
                data3:[],
                tableDataArr3:[
                    {
                        "id":1,
                        "teacher":"Name 1",
                        "teacherCode":"Teacher-1",
                        "course":"語(yǔ)文",
                        "studentList":[
                            {
                                "studentCode":"2020001",
                                "student":"學(xué)生1",
                                "score":"A",
                                "explain":""
                            },
                            {
                                "studentCode":"2020002",
                                "student":"學(xué)生2",
                                "score":"B",
                                "explain":""
                            },
                            {
                                "studentCode":"2020003",
                                "student":"學(xué)生3",
                                "score":"B",
                                "explain":""
                            },
                            {
                                "studentCode":"2020004",
                                "student":"學(xué)生4",
                                "score":"A",
                                "explain":""
                            }
                        ]
                    },
                    {
                        "id":2,
                        "teacher":"Name 2",
                        "teacherCode":"Teacher-2",
                        "course":"物理",
                        "studentList":[
                            {
                                "studentCode":"2020001",
                                "student":"學(xué)生1",
                                "score":"B",
                                "explain":""
                            },
                            {
                                "studentCode":"2020002",
                                "student":"學(xué)生2",
                                "score":"B",
                                "explain":""
                            },
                            {
                                "studentCode":"2020003",
                                "student":"學(xué)生3",
                                "score":"B",
                                "explain":""
                            }
                        ]
                    },
                    {
                        "id":3,
                        "teacher":"Name 3",
                        "teacherCode":"Teacher-3",
                        "course":"歷史",
                        "studentList":[
                            {
                                "studentCode":"2020003",
                                "student":"學(xué)生3",
                                "score":"A",
                                "explain":""
                            },
                            {
                                "studentCode":"2020004",
                                "student":"學(xué)生4",
                                "score":"A",
                                "explain":""
                            }
                        ]
                    },
                    {
                        "id":4,
                        "teacher":"Name 4",
                        "teacherCode":"Teacher-4",
                        "course":"美術(shù)",
                        "studentList":[
                            {
                                "studentCode":"2020004",
                                "student":"學(xué)生4",
                                "score":"A",
                                "explain":""
                            }
                        ]
                    }
                ],
            };
        },
        mounted() {
            setTimeout(() => {
                this.data3 = this.data2TdRowspan({tableData:this.tableDataArr3, rowspanList:'studentList'});
            }, 300);
        },
        methods: {
            onFreezeChange({column = {}, key = '', fixed = ''} = {}) {
                this.columns3 = this.columns3.map((col, index) =>{
                    if (col.key === key) {
                        col['fixed'] = fixed;
                    }
                    return col;
                });
            },
            /**
             * 2020年4月2日09:53:02 by jing_zhaoxia@sina.com
             * @param arr 需要處理的數(shù)據(jù)數(shù)組
             * @param rowspanList 合并行的數(shù)組
             * @param rowspanHoverFlag 作為鼠標(biāo)滑入的行的標(biāo)記
             * @returns {*} [Array] 將處理好的數(shù)據(jù)返回去
             */
            data2TdRowspan(params){
                let json = {};

                if (Array.isArray(params)) {
                    json.tableData = params;
                } else if(Object.prototype.toString.call(params) === '[object Object]'){
                    json = params;
                }

                let {tableData:arr = [], rowspanList = 'studentList', rowspanHoverFlag='id'} = json;

                return arr.map((row, index) =>{
                    let rowspanArr = row[rowspanList];
                    let rowspan = rowspanArr.length;

                    return rowspanArr.map((sRow, sIndex) => {
                        sIndex === 0 ? row.rowspan = rowspan : (row.rowspan = 0, row._rowspan = rowspan);

                        sRow.rowspanHoverFlag = row[rowspanHoverFlag];

                        delete row[rowspanList];

                        return { ...sRow, ...row};
                    });
                }).flat(Infinity);
            },
            handleSpan({row:{rowspan}, column:{rowRelation='', isExtended=false}}) {
                return rowRelation !== 'many' ? {rowspan} : {};
            }
        }
    };
</script>
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市宪躯,隨后出現(xiàn)的幾起案子乔宿,更是在濱河造成了極大的恐慌,老刑警劉巖访雪,帶你破解...
    沈念sama閱讀 218,755評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件详瑞,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡臣缀,警方通過(guò)查閱死者的電腦和手機(jī)坝橡,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)精置,“玉大人计寇,你說(shuō)我怎么就攤上這事≈耄” “怎么了番宁?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,138評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)赖阻。 經(jīng)常有香客問(wèn)我蝶押,道長(zhǎng),這世上最難降的妖魔是什么火欧? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,791評(píng)論 1 295
  • 正文 為了忘掉前任棋电,我火速辦了婚禮,結(jié)果婚禮上布隔,老公的妹妹穿的比我還像新娘离陶。我一直安慰自己,他們只是感情好衅檀,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,794評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布招刨。 她就那樣靜靜地躺著,像睡著了一般哀军。 火紅的嫁衣襯著肌膚如雪沉眶。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,631評(píng)論 1 305
  • 那天杉适,我揣著相機(jī)與錄音谎倔,去河邊找鬼。 笑死猿推,一個(gè)胖子當(dāng)著我的面吹牛片习,可吹牛的內(nèi)容都是我干的捌肴。 我是一名探鬼主播,決...
    沈念sama閱讀 40,362評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼藕咏,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼状知!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起孽查,我...
    開(kāi)封第一講書(shū)人閱讀 39,264評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤饥悴,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后盲再,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體西设,經(jīng)...
    沈念sama閱讀 45,724評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年答朋,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了贷揽。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,040評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡绿映,死狀恐怖擒滑,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情叉弦,我是刑警寧澤丐一,帶...
    沈念sama閱讀 35,742評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站淹冰,受9級(jí)特大地震影響库车,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜樱拴,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,364評(píng)論 3 330
  • 文/蒙蒙 一柠衍、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧晶乔,春花似錦珍坊、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,944評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至翻具,卻和暖如春履怯,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背裆泳。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,060評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工叹洲, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人工禾。 一個(gè)月前我還...
    沈念sama閱讀 48,247評(píng)論 3 371
  • 正文 我出身青樓运提,卻偏偏與公主長(zhǎng)得像蝗柔,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子民泵,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,979評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容