做一个动态表格(有单行复制添加删除功能)

1 篇文章 0 订阅

功能如下

 

<template>
    <div>
        <el-dialog
            title="提示"
            :visible.sync="dialogVisible"
            width="80%"
        >
            <dl class="multi-level-table">
                <dt>
                    <div
                        v-for="(column, c1) in columnsSimulation"
                        :key="c1"
                        class="th"
                        :style="`width: ${column.width}px`"
                    >
                        <span v-text="column.label"></span>
                    </div>
                </dt>
                <dd
                    v-for="(item, i) in dataSimulation.firstOrder"
                    :key="`${i}_1`"
                >
                    <!-- 第一行的第一个表格    后台类目-->
                    <div
                        class="td p10"
                        :style="`width: ${columnsSimulation[1].width}px`"
                    >
                        <el-input
                            v-model="item.compSkuNum"
                        />
                        <!-- 这个是添加删除组件,,,  只有一条数据禁止删除 -->
                        <AddDelButtonGroup
                            :index-list="[i]"
                            :disabled="dataSimulation.firstOrder.length === 1"
                            @operator="operatorRow"
                        />
                    </div>
                    <!-- 第一行的第二个表格 -->
                    <div
                        v-for="(strategy, s) in item.SecondLevel"
                        :key="`${s}_2`"
                        class="td-line"
                    >
                        <!-- 竞对类型 -->
                        <div
                            class="td p10"
                            :style="`width: ${columnsSimulation[1].width}px`"
                        >
                            <el-input
                                v-model="strategy.compSkuNum"
                            />
                            <AddDelButtonGroup
                                :index-list="[i, s]"
                                :disabled="item.SecondLevel.length === 1"
                                @operator="operatorRow"
                            />
                        </div>
                        <!-- 竞争品类型 -->
                        <div
                            class="td p10"
                            :style="`width: ${columnsSimulation[1].width}px`"
                        >
                            <div
                                v-for="(threeLevel, cIndex) in strategy.threeLevel"
                                :key="`${cIndex}_3`"
                                class="td-line"
                            >
                                <!-- 竞对类型 -->
                                <div
                                    class="td p10"
                                    :style="`width: ${columnsSimulation[1].width}px`"
                                >
                                    <el-input
                                        v-model="threeLevel.compSkuNum"
                                    />
                                    <AddDelButtonGroup
                                        :index-list="[i, s, cIndex]"
                                        :disabled="strategy.threeLevel.length === 1"
                                        @operator="operatorRow"
                                    />
                                </div>
                            </div>
                        </div>
                    </div>
                </dd>
            </dl>

            <span
                slot="footer"
                class="dialog-footer"
            >
                <el-button @click="dialogVisible = false">取 消</el-button>
                <el-button
                    type="primary"
                    @click="confirmDialogVisible"
                >确 定</el-button>
            </span>
        </el-dialog>
    </div>
</template>

<script>
import {
    defineComponent, toRefs, getCurrentInstance, reactive,
} from '@vue/composition-api';
import AddDelButtonGroup from './AddDelButtonGroup';

export default defineComponent({
    name: 'ConventionalPricingTableRef',
    components: { AddDelButtonGroup },
    props: {
        query: {
            type: Object,
            default: () => ({}),
        },
    },
    setup() {
        const { proxy } = getCurrentInstance();
        const initData = reactive({
            dialogVisible: true,
            // 表头
            columnsSimulation: [{
                label: '组织',
                width: 200,
            },
            {
                label: '竞对',
                width: 200,
            },
            {
                label: '标签',
                width: 200,
            }],
            // 模拟的接口数据
            dataSimulation: {
                firstOrder: [
                    {
                        compSkuNum: '生鲜',
                        SecondLevel: [{
                            compSkuNum: 'DD',
                            threeLevel: [{
                                cptType: 1,
                                compSkuNum: 'MB1',
                            }, {
                                cptType: 1,
                                compSkuNum: '新品',
                            }],
                        }, {
                            compSkuNum: 'HM',
                            threeLevel: [{
                                cptType: 1,
                                compSkuNum: '强跟价商品',
                            }],
                        }],
                    },
                    {
                        compSkuNum: '物流',
                        SecondLevel: [{
                            compSkuNum: 'PP',
                            threeLevel: [{
                                cptType: 2,
                                compSkuNum: '非MB1',
                            }],
                        }],
                    },
                ],
            },
            // 添加的数据列
            defaultDataSimulation: {
                firstOrder: [
                    {
                        SecondLevel: [{
                            threeLevel: [{
                                cptType: '',
                                compSkuNum: '',
                            }],
                            compSkuNum: '',
                            cptType: '',
                        }],
                        compSkuNum: '',
                        cptType: '',
                    },
                ],
            },
        });
        const operatorRow = (obj) => {
            // 这个深拷贝是封装好的, 可以用其他深拷贝
            const { cloneDeep } = proxy.$tools;
            const { isAdd, indexList } = obj || {};
            const indexLen = indexList.length;
            const sourceData = proxy.$tools.deepClone(initData.dataSimulation.firstOrder); // 拷贝一下原数据,等下操作这个数据的增删
            console.log('isAdd', isAdd);
            console.log('indexList', indexList);
            console.log('sourceData', sourceData);
            switch (indexLen) {
                case 1: // 添加第一列
                    if (isAdd === 'copy') {
                        // 实现逻辑是如果复制的是组织,那么需要将组织项清空,如果不深拷贝的话,会影响原数据
                        const copyValue = sourceData[indexList[0]];
                        const deepCloneCopy = proxy.$tools.deepClone(copyValue);
                        deepCloneCopy.compSkuNum = null;
                        sourceData.splice(+indexList[0] + 1, 0, cloneDeep(deepCloneCopy));
                    } else if (isAdd) {
                        sourceData.splice(+indexList[0] + 1, 0, cloneDeep(initData.defaultDataSimulation.firstOrder[0]));
                    } else {
                        sourceData.splice(+indexList[0], 1);
                    }
                    break;
                case 2:// 添加第二列
                    if (isAdd === 'copy') {
                        // 要复制的数据
                        const copyValue = sourceData[indexList[0]].SecondLevel[indexList[1]];
                        const deepCloneCopy = proxy.$tools.deepClone(copyValue);
                        deepCloneCopy.compSkuNum = null;
                        sourceData[+indexList[0]].SecondLevel.splice(+indexList[1] + 1, 0, cloneDeep(deepCloneCopy));
                    } else if (isAdd) {
                        sourceData[+indexList[0]].SecondLevel.splice(+indexList[1] + 1, 0, cloneDeep(initData.defaultDataSimulation.firstOrder[0].SecondLevel[0]));
                    } else {
                        sourceData[+indexList[0]].SecondLevel.splice(+indexList[1], 1);
                    }
                    break;
                case 3:// 添加第三列
                    if (isAdd === 'copy') {
                        // 要复制的数据
                        const copyValue = sourceData[indexList[0]].SecondLevel[indexList[1]].threeLevel[indexList[2]];
                        const deepCloneCopy = proxy.$tools.deepClone(copyValue);
                        deepCloneCopy.compSkuNum = null;
                        sourceData[+indexList[0]].SecondLevel[+indexList[1]].threeLevel.splice(+indexList[2] + 1, 0, cloneDeep(deepCloneCopy));
                    } else if (isAdd) {
                        sourceData[+indexList[0]].SecondLevel[+indexList[1]].threeLevel.splice(+indexList[2] + 1, 0, cloneDeep(initData.defaultDataSimulation.firstOrder[0].SecondLevel[0].threeLevel[0]));
                    } else {
                        sourceData[+indexList[0]].SecondLevel[+indexList[1]].threeLevel.splice(+indexList[2], 1);
                    }
                    break;
                default:
                    break;
            }

            initData.dataSimulation.firstOrder = sourceData;
        };

        // 点击确认
        const confirmDialogVisible = () => {
            console.log(initData.dataSimulation.firstOrder);
        };
        return {
            operatorRow,
            ...toRefs(initData),
            confirmDialogVisible,

        };
    },
});
</script>

<style lang="scss" scoped>
// 一些样式
$tBorderColor: #edf0f5;
.multi-table-wrapper {
    width: 100%;
    overflow-x: auto;
}
.multi-level-table {
    min-width: 100%;
    display: table;
    border: $tBorderColor 1px solid;
    border-bottom: none;
    dt,
    dd {
        width: 100%;
        margin: 0;
        padding: 0;
        border-bottom: $tBorderColor 1px solid;
        display: table;
        table-layout: fixed;
        line-height: 20px;
        .th,
        .td {
            display: table-cell;
            vertical-align: middle!important;
            font-size: 12px;
            border-right: $tBorderColor 1px solid;
            &:last-child {
                border-right: none;
            }
            line-height: 22px;
            box-sizing: border-box;
            &.p10 {
                padding: 0 10px;
            }
            &.inner {
                padding: 0 10px;
                height: 120px;
            }
            &.inner-mini {
                padding: 0 10px;
                height: 80px;
            }
        }
        .th {
            padding: 10px;
        }
        .td-line {
            width: 100%;
            display: table;
            table-layout: fixed;
            border-bottom: $tBorderColor 1px solid;
            &:last-child {
                border-bottom: none;
            }
        }
        .error-tips {
            margin: 0;
            padding: 5px 0;
            color: #ff0000;
        }
    }
    dt {
        background: #f5f6f7;
        font-weight: bold;
    }
    .border-box {
        box-sizing: border-box
    }
    .table {
        display: table;
    }
}
</style>

AddDelButtonGroup组件

<template>
    <div class="btn-wrapper">
        <el-button
            type="text"
            @click="operatorRow('copy')"
        >
            复制
        </el-button>
        <el-button
            type="text"
            @click="operatorRow(true)"
        >
            添加
        </el-button>
        <el-button
            type="text"
            v-bind="$attrs"
            class="del-btn"
            @click="operatorRow(false)"
        >
            删除
        </el-button>
    </div>
</template>

<script>
export default {
    name: 'AddDelButtonGroup',
    props: {
        indexList: {
            type: Array,
            required: true,
        },
    },
    data() {
        return {

        };
    },
    methods: {
        // 添加\删除行
        operatorRow(isAdd) {
            this.$emit('operator', { isAdd, indexList: this.indexList.map((index) => `${index}`) });
        },
    },
};
</script>

<style lang="scss" scoped>
.btn-wrapper {
    margin-top: 10px;
}
.del-btn {
    color: #ff0000;
    &:disabled {
        color: #B0B3B8;
    }
}
</style>

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值