鍍金池/ 問答/HTML/ vue項目自己封裝了一個table組件,顯示隱藏列操作非常慢?

vue項目自己封裝了一個table組件,顯示隱藏列操作非常慢?

自己嘗試著封裝一個通用的table組件,里面有一個顯示、隱藏列的功能,如下圖:

圖片描述

可以通過點擊“顯示/隱藏列”下面的列名稱來顯示隱藏表格對應的列,但是當我多次(反復)點擊時,發(fā)現(xiàn)table里面的列顯示、隱藏的動作非常非常慢(好像有延遲),有時候點擊后沒反應,必須鼠標移開(點擊的列名稱)后,table的顯示或隱藏才能完成,這是什么問題呢?

代碼如下:

注:不想復制的朋友可以直接 下載源碼 ,里面只有這個demo,npm install 后就可以查看了,謝謝!

myTable.vue組件

<template>
    <div class="tab-wrapper">
        <div class="tab-title-wrapper">
            <div class="tab-title">table測試組件</div>
            <div class="tab-actions" @mouseover="showTableAction = true" @mouseout="showTableAction = false">
                顯示/隱藏列
                <div class="tab-action-item-wrapper" v-show="showTableAction">
                    <div v-for="head in heades" :key="head.key" @click="showColumn(head)" :class="{'active': head.isShow != false}">{{ head.label }}</div>
                </div>
            </div>
        </div>
        <table>
            <thead>
                <tr>
                    <th v-for="head in heades" v-show="head.isShow != false" :key="head.key">{{ head.label }}</th>
                </tr>
            </thead>
            <tbody>
                <tr v-for="(item, idx) in tabDatas" :key="idx">
                    <td v-for="(head, idx2) in heades" v-show="head.isShow != false" :key="head.key + idx2">
                        {{ item[head.key] }}
                    </td>
                </tr>
            </tbody>
        </table>
    </div>
</template>

<script>
export default {
    name: 'table-component',
    props: {
        tabHeades: Array,
        tabDatas: Array
    },
    data() {
        return {
            showTableAction: false,
            heades: []
        }
    },
    methods: {
        showColumn(head) {
            head.isShow = !head.isShow
            console.log(JSON.stringify(head))
        }
    },
    mounted() {
        this.heades = this.tabHeades;
    }
}
</script>

<style scoped>

.tab-wrapper, table{
    width: 100%;
}

thead th{
    cursor: pointer;
}

.tab-title-wrapper {
    display: flex;
}

.tab-title-wrapper .tab-title{
    flex: 1;
    text-align: left;
}

.tab-title-wrapper .tab-actions{
    position: relative;
    cursor: pointer;
}

.tab-title-wrapper .tab-actions .tab-action-item-wrapper{
    position: absolute;
    text-align: left;
}

.tab-title-wrapper .tab-actions .tab-action-item-wrapper .active{
    background: #ccc
}
</style>

父組件:

<template>
    <div>
        <my-table :tabHeades='tabHeades' :tabDatas='tabDatas'></my-table>
    </div>
</template>

<script>
import MyTable from './myTable'
export default {
    name: 'table-use',
    data() {
        return {
            tabHeades: [
                {label: '編號', key: 'id'},
                {label: '訂單號', key: 'orderId', isShow: false},
                {label: '用戶名', key: 'username'}
            ],
            tabDatas: [
                {'id': 1, 'orderId': '10001', 'username': '小張'},
                {'id': 3, 'orderId': '10003', 'username': '小王'},
                {'id': 4, 'orderId': '10004', 'username': 'aaa'},
                {'id': 5, 'orderId': '10005', 'username': 'bbb'},
                
            ]
        }
    },
    components: {
        MyTable
    }
}
</script>
回答
編輯回答
孤巷

改一下賦值的方法

        showColumn(head) {
            // head.isShow = !head.isShow;
            this.$set(head, 'isShow', !head.isShow);
            console.log(JSON.stringify(head));
        }
2017年6月11日 19:37
編輯回答
厭遇

深層賦值監(jiān)聽不到,用forceUpdate把

2017年7月5日 06:23
編輯回答
久礙你

看到標題說卡,以為是列表數(shù)據(jù)量巨大,進來看,發(fā)現(xiàn)才四條數(shù)據(jù)。。。

如你所說:
“隱藏的動作非常非常慢(好像有延遲),有時候點擊后沒反應,必須鼠標移開(點擊的列名稱)后,table的顯示或隱藏才能完成”,問題在這里,那么到底為什么呢???

鼠標離開操作是一個很好的啟發(fā),與mouseout有關(guān)的你只在一個地方使用了。仔細想想 發(fā)生了什么,點擊click并沒有反應,然后鼠標移開生效了,發(fā)生了什么。
鼠標移開發(fā)生了模板重繪,順便導致你的 table表格更新。

其實你的根源不在于 數(shù)組變動,而在于你的 數(shù)據(jù)初始化不包含 isShow屬性,后來新增加的導致無法監(jiān)聽。

tabHeades: [
    {label: '編號', key: 'id'},
    {label: '訂單號', key: 'orderId', isShow: false},
    {label: '用戶名', key: 'username'}
],

把其他兩條數(shù)據(jù)的isShow補全。

還有一個需要注意的地方
你在子組件mounted接受的 props的數(shù)據(jù)賦值給本地data

this.heades = this.tabHeades;

由于這是一個引用類型的數(shù)據(jù),傳遞的僅僅是地址引用。所以在click的時候,你做了數(shù)據(jù)更改,實際上父組件的數(shù)據(jù)一樣發(fā)生了更改。如果你想保持單純,請在子組件使用 深拷貝操作。

2018年4月14日 05:06