Vue2x el-tabs动态增删标签页

一、需求

项目中在线sql页面有个新需求,需要对执行sql的结果进行展示,每执行一次需要展示一个结果tab页面,最多不超过10个,方便查看执行的结果,如图所示:

二、思路及功能实现

既然是动态增删,而且在Log tab后面,所以使用数组来存放结果tab,使用Element-UI的el-tabs组件进行展示。而结果tab页面里面展示后台返回的很多条列表数据,用Element-UI的el-table组件来展示。

代码如下:

                <el-tabs
                    type="border-card"
                    v-model="editableTabsValue"
                    @tab-click="handleTabLogClick"
                    @tab-remove="removeTab"
                    class="inner-tabs"
                >
                    <el-tab-pane name="log">
                        <span slot="label"> Log</span>
                        <el-table
                            class="logTable"
                            :data="logData"
                        >
                            <el-table-column
                                type="index"
                                width="50"
                                label="*"
                            >
                            </el-table-column>
                            <el-table-column label="command">
                                <template slot-scope="scope">
                                    <el-popover
                                        trigger="hover"
                                        placement="top"
                                        :visible-arrow="false"
                                    >
                                        <div
                                            class="popover-content"
                                            v-html="scope.row.command"
                                        ></div>
                                        <template #reference>
                                            <span>{{ scope.row.command | formaterEllipsis(7) }}</span>
                                        </template>
                                    </el-popover>
                                </template>
                            </el-table-column>
                            <el-table-column label="exec">
                                <template slot-scope="scope">
                                    <el-popover
                                        trigger="hover"
                                        placement="top"
                                        :visible-arrow="false"
                                    >
                                        <div
                                            class="popover-content"
                                            v-html="scope.row.exec"
                                        ></div>
                                        <template #reference>
                                            <span>{{ scope.row.exec | formaterEllipsis(7) }}</span>
                                        </template>
                                    </el-popover>
                                </template>
                            </el-table-column>
                            <el-table-column label="message">
                                <template slot-scope="scope">
                                    <span>{{ scope.row.message | formaterEllipsis(7) }}</span>
                                </template>
                            </el-table-column>
                            <el-table-column label="operUserCode">
                                <template slot-scope="scope">
                                    <span>{{ scope.row.operUserCode }}</span>
                                </template>
                            </el-table-column>
                            <el-table-column label="status">
                                <template slot-scope="scope">
                                    <span>{{ scope.row.status }}</span>
                                </template>
                            </el-table-column>
                        </el-table>
                        <!-- 分页组件 -->
                        <Pagination
                            :child-msg="logPageparm"
                            @callFather="callLogFather"
                        />
                    </el-tab-pane>
                    <el-tab-pane
                        v-for="(tab, index) in editableTabs"
                        :closable="tab.closable"
                        :key="tab.name"
                        :label="tab.label"
                        :name="tab.name"
                    >
                        <el-table
                            class="resultTable"
                            :data="tab.tableData"
                            max-height="500"
                        >
                            <el-table-column
                                type="index"
                                width="80"
                            >
                                <template slot="header">
                                    <span>*</span><el-button
                                        type="text"
                                        @click="handleDownload(tab.code)"
                                        class="downloadBtn"
                                    >下载</el-button>
                                </template>
                            </el-table-column>
                            <el-table-column
                                v-for="(v, ind) in tab.dynamicCols"
                                :key="ind"
                                :prop="v"
                            >
                                <template slot-scope="scope">
                                    <span>{{ scope.row[v] }}</span>
                                </template>
                            </el-table-column>
                        </el-table>
                    </el-tab-pane>
                </el-tabs>
    // 调用执行sql接口
                executeSql(params)
                    .then((res) => {
                        if (res.data.code === 200) {
                            let dataArray = res.data.data;
                            // 把字符数组转为对象数组
                            let tempArray = [];
                            let obj = {};
                            dataArray.forEach(function (item, index) {
                                obj = Object.assign({}, item); //Object.assign将源对象中的所有属性分配到目标对象,返回目标对象
                                tempArray.push(obj);
                            });
                            if (tempArray) {
                                // this.editableTabsValue = 'result1';
                                // 找到最长的属性列
                                const longestColumn = tempArray.reduce(
                                    (longest, obj) => {
                                        const columns = Object.keys(obj); 
                                        const longestColumnLength =
                                            Object.keys(longest).length;
                                        if (
                                            columns.length > longestColumnLength
                                        ) {
                                            return obj;
                                        } else {
                                            return longest;
                                        }
                                    },
                                    {}
                                );
                                console.log(longestColumn);
                                let dynamicCols = Object.keys(longestColumn);
                                // console.log(dynamicCols)
                                //添加tab
                                this.addTab(
                                    tempArray,
                                    deleteEnterCode,
                                    dynamicCols
                                );
                            }
                        }
                    })
                    .catch((error) => {
                        console.log(error);
                    });
         // 新增tab页事件
        addTab(arr, code, columns) {
            // let newTabName = ++this.tabIndex + '';
            // name: newTabName,
            // 每次执行一次executionCount+1
            this.executionCount++;
            // 限制只显示10个tab
            if (this.executionCount > 10) {
                return false;
            }
            let obj = {
                label: "结果" + (this.editableTabs.length + 1),
                name: "result" + (this.editableTabs.length + 1),
                closable: true,
                tableData: arr, //每次执行的列表数据
                code: code, //每次执行的sql
                dynamicCols: columns, //动态列
            };
            this.editableTabs.push(obj);
            this.editableTabsValue = obj.name;
        },
        // 关闭tab页事件
        removeTab(targetName) {
            // console.log('remove', targetName)
            let tabs = this.editableTabs;
            if (tabs.length <= 1) {
                return false;
            }
            let activedTabName = this.editableTabsValue;
            if (activedTabName === targetName) {
                tabs.forEach((tab, index) => {
                    if (tab.name === targetName) {
                        let nextTab = tabs[index + 1] || tabs[index - 1];
                        if (nextTab) {
                            activedTabName = nextTab.name;
                        }
                    }
                });
            }
            this.editableTabsValue = activedTabName;
            this.editableTabs = tabs.filter((tab) => tab.name !== targetName);
        },

三、遇到的问题

每个结果tab标签中的列表数据的列显示错误

四、原因分析

排查后发现后台返回的列表数据的列不是固定的,我显示是按照固定列进行展示

五、解决方案

把后台返回的二维字符数组转为一维对象数组,遍历对象数组,找到最长的属性列,根据最长的属性列动态显示列表数据

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
动态增加 el-tabs标签,你可以通过修改绑定的数据来实现。首先,在 el-tabs 组件中,你需要有一个 `v-model` 绑定一个变量,用于存储当前选中的标签的索引。然后,你可以通过修改绑定的数组,来增加新的标签。 举个例子,假设你有以下的 el-tabs: ```html <el-tabs v-model="activeTab"> <el-tab-pane label="Tab 1">Content of Tab Pane 1</el-tab-pane> <el-tab-pane label="Tab 2">Content of Tab Pane 2</el-tab-pane> </el-tabs> ``` 其中,`activeTab` 是绑定的变量,用于存储当前选中的标签的索引。 如果你想要动态增加一个标签,你可以添加一个按钮,绑定一个方法,在方法中修改绑定的数组,例如: ```html <el-button @click="addTab">Add Tab</el-button> ``` ```javascript methods: { addTab() { this.tabs.push({ label: 'New Tab', content: 'Content of New Tab' }) } } ``` 在上面的代码中,我们添加了一个 `addTab` 方法,当按钮被点击时,该方法会向 `tabs` 数组中添加一个新的元素,包含标签标签和内容。 最后,我们需要更新 `el-tabs` 组件的模板,让它使用动态的数据来渲染标签: ```html <el-tabs v-model="activeTab"> <el-tab-pane v-for="(tab, index) in tabs" :key="index" :label="tab.label"> {{ tab.content }} </el-tab-pane> </el-tabs> ``` 在上面的代码中,我们使用 `v-for` 循环遍历 `tabs` 数组,动态渲染标签。注意,我们需要给每个标签加上 `:key` 属性,以便 Vue 可以正确地跟踪哪些标签已被添加或删除。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值