表格可行内编辑,列可动态显示隐藏

小颖前段时间做的项目里需要实现一个功能:表格可以行内编辑,并且表格的部分列是固定的,部分列随着右上角勾选的可显示列的变化而变化,在右侧我勾选了那些列,表格才能显示那些列,如果我没有勾选则不显示。

具体效果如图所示:

具体代码:

小颖用的vue+Ant Design of Vue

html:

<template>
    <div class="table-dynamic-column">
        <p class="txt-right">
            <a-dropdown :trigger="['click']">
                <i class="fa fa-bars ant-dropdown-link"></i>
                <a-menu slot="overlay">
                    <a-menu-item key="1" :disabled="true" class="have-disabled">
                        <a-checkbox :indeterminate="indeterminate"
                                    @change="selectAllFun" :checked="checked">全选/反选
                        </a-checkbox>
                    </a-menu-item>
                    <a-menu-item key="2" :disabled="true" class="have-disabled">
                        <a-checkbox-group v-model="showColumn" @change="hideColumnChange()">
                            <div class="dropdown-menu-item-tem" v-for="(item,index) in movingColumns" @click="hideColumnFun(index)"
                                 :key="index">
                                <a-checkbox :value="item.dataIndex">
                                    <span class="hide-column-tem">{{item.title}}</span>
                                </a-checkbox>
                            </div>
                        </a-checkbox-group>
                    </a-menu-item>
                </a-menu>
            </a-dropdown>
        </p>
        <a-table :columns="columns" :dataSource="data" bordered>
            <template
                    v-for="col in editColumnDt"
                    :slot="col"
                    slot-scope="text, record"
            >
                <div :key="col">
                    <a-input
                            v-if="record.editable"
                            style="margin: -5px 0"
                            :value="text"
                            @change="e => handleChange(e.target.value, record.key, col)"
                    />
                    <template v-else>{{text}}</template>
                </div>
            </template>
            <template slot="operation" slot-scope="text, record">
                <div class="editable-row-operations" v-if="columns.length>3">
                    <span v-if="record.editable">
                        <a @click="() => save(record.key)">Save</a>
                        <a-popconfirm title="Sure to cancel?" @confirm="() => cancel(record.key)">
                            <a>Cancel</a>
                        </a-popconfirm>
                    </span>
                    <span v-else><a @click="() => edit(record.key)">Edit</a></span>
                </div>
                <div v-else>暂无操作</div>
            </template>
        </a-table>
    </div>
</template>

js:

<script>
    const columns = [
        {
            title: 'name',
            dataIndex: 'name',
            scopedSlots: { customRender: 'name' },
        },
        {
            title: 'age',
            dataIndex: 'age',
            scopedSlots: { customRender: 'age' },
        },
        {
            title: 'operation',
            dataIndex: 'operation',
            scopedSlots: { customRender: 'operation' },
        },
    ];

    const data = [];
    for (let i = 0; i < 100; i++) {
        data.push({
            key: i.toString(),
            name: `Edrward ${i}`,
            age: 32,
            phone: 15388646322,
            address: `London Park no. ${i}`,
        });
    }
    export default {
        name: "tableDynamicColumn",
        data() {
            this.cacheData = data.map(item => ({ ...item }));
            return {
                checked: true,
                indeterminate: false,
                data,
                columns,
                editColumnDt: [],//可编辑的列
                movingColumns: [],//动态显示列
                showColumn: [],//不隐藏的列
                hideColumnIndex: null,//当前点的那个复选框
            };
        },
        mounted() {
            this.getDynamicColumn()
        },
        methods: {
            //获取动态列信息
            getDynamicColumn(){
                //    调接口获取动态列
                const that = this
                const responseData = [
                    {
                        title: 'address',
                        dataIndex: 'address',
                        scopedSlots: {customRender: 'address'},
                    }, {
                        title: 'phone',
                        dataIndex: 'phone',
                        scopedSlots: {customRender: 'phone'},
                    }
                ]
                const newData = [...responseData]
                newData.forEach(function (item, index) {
                    that.editColumnDt[index] = item.dataIndex
                    that.showColumn[index] = item.dataIndex
                })
                this.movingColumns = newData
                const operation = this.columns.splice(2, 1)
                this.columns = this.columns.concat(newData)
                this.columns = this.columns.concat(operation)
            },
            handleChange(value, key, column) {
                const newData = [...this.data];
                const target = newData.filter(item => key === item.key)[0];
                if (target) {
                    target[column] = value;
                    this.data = newData;
                }
            },
            edit(key) {
                const newData = [...this.data];
                const target = newData.filter(item => key === item.key)[0];
                if (target) {
                    target.editable = true;
                    this.data = newData;
                }
            },
            save(key) {
                const newData = [...this.data];
                const target = newData.filter(item => key === item.key)[0];
                if (target) {
                    delete target.editable;
                    this.data = newData;
                    this.cacheData = newData.map(item => ({ ...item }));
                }
            },
            cancel(key) {
                const newData = [...this.data];
                const target = newData.filter(item => key === item.key)[0];
                if (target) {
                    Object.assign(target, this.cacheData.filter(item => key === item.key)[0]);
                    delete target.editable;
                    this.data = newData;
                }
            },
            //全选/反选
            selectAllFun(e){
                this.checked = e.target.checked
                this.indeterminate = false
                if(e.target.checked){//全选
                    this.showColumn = this.movingColumns.map(function (item) {
                        item.hideCol = false
                        return item.dataIndex
                    })
                    const operation = this.columns.splice(2, 1)
                    this.columns = this.columns.concat(this.movingColumns)
                    this.columns = this.columns.concat(operation)
                }else {//反选
                    this.showColumn = []
                    this.movingColumns.map(function (item) {
                        item.hideCol = true
                    })
                    this.movingColumnFun()
                }
            },
            //右侧显示隐藏的复选框的change事件
            hideColumnChange(){
                this.indeterminate = false
                this.checked = false
                const newData = [...this.showColumn]
                //全选
                if (newData.length === this.movingColumns.length) {
                    this.checked = true
                }
                //半选样式
                if (newData.length !== 0 && newData.length < this.movingColumns.length) {
                    this.indeterminate = true
                }
                const index = this.hideColumnIndex
                const target = newData.filter(item => this.movingColumns[index].dataIndex === item)[0];
                if (target) {
                    this.$set(this.movingColumns[index], 'hideCol', false)
                } else {
                    this.$set(this.movingColumns[index], 'hideCol', true)
                }
                this.movingColumnFun()
            },
            movingColumnFun(){
                const _movingColumns = this.movingColumns.filter(item => {
                    if (!item.hideCol) {
                        return item
                    }
                })
                const operation = this.columns.splice(this.columns.length - 1, 1)//截取操作列
                const _columns = this.columns.slice(0, 2)//先回归固定列
                this.columns = _columns.concat(_movingColumns)
                this.columns = this.columns.concat(operation)
            },
            //隐藏列单独勾选
            hideColumnFun(index) {
                this.hideColumnIndex = index
            }
        }
    }
</script>

css:

<style scoped>
    .editable-row-operations a {
        margin-right: 8px;
    }
    .txt-right{
        padding: 20px 5px 10px 0;
    }
</style>

具体实现请移步:小颖Git

原文地址:https://www.cnblogs.com/yingzi1028/p/12084355.html