给antdv 1.78 Vue2版本的a-table增加显示隐藏列和列宽调整还有列位置拖动功能并将数据永久保存在后端

列位置拖动功能需要安装插件draggable,并在页面中引入。

//npm方式安装
npm i -S vuedraggable

//或使用yarn安装
yarn add vuedraggable

其他的废话不说直接上代码:

HTML部分:

<template>
    <div>
        <a-button @click="toggleColumnsVisible">显示/隐藏列</a-button>
        <a-table :columns="newColumns" :dataSource="dataSource"> </a-table>
    </div>
</template>

JS部分:

<script>
import { getAction, postAction } from '@api/manage'
import draggable from 'vuedraggable'

export default {
    name: 'showColumnsTable',
    components: {
        draggable,
    },
    data() {
        return {
            tableId: 'showColumnsTable',
            dataSource: [
                {
                    key: '1',
                    name: '胡彦斌',
                    age: 32,
                    address: '西湖区湖底公园1号',
                },
                {
                    key: '2',
                    name: '胡彦祖',
                    age: 42,
                    address: '西湖区湖底公园1号',
                },
            ],
            columns: [
                {
                    title: '姓名',
                    dataIndex: 'name',
                    key: 'name',
                    width: 100,
                    visible: true,
                },
                {
                    title: '年龄',
                    dataIndex: 'age',
                    key: 'age',
                    width: 100,
                    visible: true,
                },
                {
                    title: '住址',
                    dataIndex: 'address',
                    key: 'address',
                    width: 100,
                    visible: true,
                },
                {
                    title: '操作',
                    dataIndex: 'action',
                    key: 'action',
                    fixed: 'right',
                    width: 100,
                    visible: true,
                },
            ],
            newColumns: [],
        }
    },
    created() {
        this.getVisibleColumns()
    },
    methods: {
        getVisibleColumns() {
            getAction('后端查询接口', { tableId: this.tableId })
                .then((res) => {
                    if (res.result === null) {
                        this.updateVisibleColumns()
                        return
                    }
                    if (res.code !== 200) {
                        this.updateVisibleColumns()
                        return
                    }
                    let newColumns = JSON.parse(res.result)
                    //给columns赋保存的值,不直接将回参直接覆盖columns,是因为columns中可能有新增的列,再就是columns中的 customRender: function 是无法保存到后端的
                    this.columns.forEach((column) => {
                        let newColumn = newColumns.find((item) => item.dataIndex === column.dataIndex)
                        if (newColumn) {
                            column.visible = newColumn.visible
                            column.width = newColumn.width
                        }
                    })
                    this.columns.sort((a, b) => {
                        const indexA = newColumns.findIndex((item) => item.title === a.title)
                        const indexB = newColumns.findIndex((item) => item.title === b.title)
                        return indexA - indexB
                    })
                    this.updateVisibleColumns()
                })
                .catch((err) => {
                    this.updateVisibleColumns()
                })
        },
        toggleColumnsVisible() {
            let cloneColumns = JSON.parse(JSON.stringify(this.columns))
            // 弹出显示隐藏列的对话框
            this.$confirm({
                title: '显示/隐藏列',
                content: () => (
                    <div>
                        <draggable v-model={this.columns}>
                            {this.columns.map((column) => (
                                // 通过fixed属性来判断是否是固定列,固定列不允许隐藏和调整位置
                                <div class={column.fixed === 'right' ? 'notDisplay' : ''}>
                                    <div style="width:49%; float: left;display:flex;align-items: center;">
                                        <svg
                                            focusable="false"
                                            className=""
                                            data-icon="drag"
                                            width="1em"
                                            height="1em"
                                            fill="currentColor"
                                            aria-hidden="true"
                                            viewBox="64 64 896 896"
                                            style="margin-right:3px;cursor: pointer"
                                        >
                                            <path d="M909.3 506.3L781.7 405.6a7.23 7.23 0 00-11.7 5.7V476H548V254h64.8c6 0 9.4-7 5.7-11.7L517.7 114.7a7.14 7.14 0 00-11.3 0L405.6 242.3a7.23 7.23 0 005.7 11.7H476v222H254v-64.8c0-6-7-9.4-11.7-5.7L114.7 506.3a7.14 7.14 0 000 11.3l127.5 100.8c4.7 3.7 11.7.4 11.7-5.7V548h222v222h-64.8c-6 0-9.4 7-5.7 11.7l100.8 127.5c2.9 3.7 8.5 3.7 11.3 0l100.8-127.5c3.7-4.7.4-11.7-5.7-11.7H548V548h222v64.8c0 6 7 9.4 11.7 5.7l127.5-100.8a7.3 7.3 0 00.1-11.4z"></path>
                                        </svg>
                                        <a-checkbox v-model={column.visible}>{column.title}</a-checkbox>
                                    </div>
                                    <div style="width:49%;margin-left: 51%;">
                                        <span style="margin-right:3px">列宽:</span>
                                        <a-input-number
                                            size="small"
                                            style="width:60%"
                                            step="10"
                                            v-model={column.width}
                                        ></a-input-number>
                                    </div>
                                </div>
                            ))}
                        </draggable>
                    </div>
                ),
                onOk: () => {
                    this.updateVisibleColumns()
                    this.saveVisibleColumns()
                },
                onCancel: () => {
                    this.columns.forEach((column) => {
                        let newColumn = cloneColumns.find((item) => item.dataIndex === column.dataIndex)
                        if (newColumn) {
                            column.visible = newColumn.visible
                            column.width = newColumn.width
                        }
                    })
                    this.columns.sort((a, b) => {
                        const indexA = cloneColumns.findIndex((item) => item.title === a.title)
                        const indexB = cloneColumns.findIndex((item) => item.title === b.title)
                        return indexA - indexB
                    })
                },
            })
        },
        updateVisibleColumns() {
            // 更新显示的列配置
            this.newColumns = this.columns.filter((column) => column.visible)
        },
        saveVisibleColumns() {
            // 将显示隐藏列的数据存储到后端
            let params = {
                hiddenColumns: JSON.stringify(this.columns),
                tableId: this.tableId,
            }
            postAction('后端保存接口', params).then((res) => {
                if (res.success) {
                    this.$message.success('操作成功')
                } else {
                    this.$message.error(res.message)
                }
            })
        },
    },
}
</script>

后端接口的逻辑为:一个tableId字段用于区分table,一个hiddenColumns字段为JSON格式化后的前端列数据,一个userId字段用于区分用户(从token里取),新增编辑使用同一接口,如果tableId不存在则为新增,否则为编辑。

CSS部分:

<style scoped>
.notDisplay {
    display: none;
}
</style>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值