vue3+element plus 表格自动跨列,方便快捷实现

文章描述了在Vue项目中使用ElementUI的el-table组件展示统计数据的过程,涉及如何通过自定义span-method实现日期、分类等列的动态行跨列显示以及获取后台接口数据。

效果图:

直接上代码:


<template>
    <div class="stat-box"> 
        <el-table :data="tableData" height="800"  border show-summary style="width: 100%" :span-method="objectSpanMethod"> 
            <el-table-column prop="belong_date" label="日期" width="180" /> 
            <el-table-column prop="cate_name" label="分类" width="180" /> 
            <el-table-column prop="season_name" label="季节" width="180" />
            <el-table-column prop="not_receival" label="欠回货数" />
            <el-table-column prop="not_receival_out" label="超期数" /> 
        </el-table>   

        
    </div>
</template>


<script setup lang="ts">
import { ref, provide, onMounted,cloneVNode } from 'vue' 
import {getStatList } from "/@/api/backend/purchaseStat"; 
const tableData = ref([])  
const objectSpanMethod = ({
    row,
    column,
    rowIndex,
    columnIndex
}) => {
    const columnsToSpan = ['belong_date', 'cate_name', 'season_name']; // 列名数组 , 'not_receival','not_receival_out'
    if (columnsToSpan.includes(column.property)) {
        if (rowIndex === 0 || row[column.property] !== tableData.value[rowIndex - 1][column.property]) {
            // 如果是相同 "NAME" 的第一行,则返回正确的 rowspan 和 colspan
            let rowspan = 1;
            for (let i = rowIndex + 1; i < tableData.value.length; i++) {
                if (tableData.value[i][column.property] === row[column.property]) {
                    rowspan++;
                    tableData.value[i]._rowspan = 0; // 隐藏后续行的 "NAME"
                } else {
                    break;
                }
            }
            return {
                rowspan,
                colspan: 1
            };
        }
        return {
            rowspan: 0,
            colspan: 0
        }; // 隐藏相同 "NAME" 的后续行
    }
    return {
        rowspan: 1,
        colspan: 1
    };
}
 
onMounted(() => { 
    getStatList().then((res) => {
        console.log(res)

        tableData.value = res.data.list
    }) 
}) 
</script>

<think>我们使用Vue3ElementPlus实现表格的拖拽排序功能。注意,这里指的是表格的拖拽(即表头的重新排序),而是行的拖拽。实现思路:1.使用ElementPlus表格组件,并动态绑定数据(columns),这样我们可以通过改变顺序来重新渲染表格。2.使用Sortable.js实现拖拽功能。注意:我们需要在表头元素上应用Sortable,而表格体。3.由于ElementPlus表格结构,我们需要找到正确的表头容器。通常,表头的容器是`.el-table__header-wrapperthead`,但具体可能需要根据实际情况调整。步骤:a.安装Sortable.js(如果尚未安装):npminstallsortablejs--saveb.Vue组件中引入Sortable。c.表格渲染完成后,初始化Sortable实例,并绑定到表头行(thead>tr)。d.在拖拽结束后(onEnd事件),更新数据顺序,并重新渲染表格。注意:ElementPlus表格是通过一个数组(如columns)来定义的,我们只需要改变这个数组的顺序,然后重新绑定即可。具体代码实现如下:1.模板部分(使用ElementPlus的el-table):<template><el-table:data="tableData"borderstyle="width:100%"><el-table-columnv-for="columnintableColumns":key="column.prop":prop="column.prop":label="column.label"/></el-table></template>2.脚本部分:<scriptsetup>import{ref,onMounted,nextTick}from&#39;vue&#39;importSortablefrom&#39;sortablejs&#39;//表格数据consttableData=ref([{date:&#39;2016-05-03&#39;,name:&#39;Tom&#39;,address:&#39;No.189,GroveSt,LosAngeles&#39;},{date:&#39;2016-05-02&#39;,name:&#39;Tom&#39;,address:&#39;No.189,GroveSt,LosAngeles&#39;},{date:&#39;2016-05-04&#39;,name:&#39;Tom&#39;,address:&#39;No.189,GroveSt,LosAngeles&#39;},{date:&#39;2016-05-01&#39;,name:&#39;Tom&#39;,address:&#39;No.189,GroveSt,LosAngeles&#39;},])//表格定义(初始顺序)consttableColumns=ref([{prop:&#39;date&#39;,label:&#39;Date&#39;},{prop:&#39;name&#39;,label:&#39;Name&#39;},{prop:&#39;address&#39;,label:&#39;Address&#39;}])//初始化拖拽constinitColumnDrag=()=>{//等待DOM更新nextTick(()=>{//获取表头的thead>tr元素constthead=document.querySelector(&#39;.el-table__header-wrappertheadtr&#39;)if(!thead)return//初始化SortableSortable.create(thead,{animation:150,//动画//设置拖拽元素为thdraggable:&#39;th&#39;,//拖拽结束时更新顺序onEnd:(event)=>{const{oldIndex,newIndex}=eventif(oldIndex===newIndex)return//复制当前数组constnewColumns=[...tableColumns.value]//删除旧的const[removed]=newColumns.splice(oldIndex,1)//插入到新的位置newColumns.splice(newIndex,0,removed)//更新顺序tableColumns.value=newColumns}})})}//在挂载后初始化拖拽onMounted(()=>{initColumnDrag()})</script>注意点:-必须等待表格渲染完成后再初始化Sortable,因此我们使用nextTick确保DOM已更新。-在拖拽结束后,我们通过splice方法调整数组的顺序,然后重新赋值给tableColumns,这样表格就会重新渲染。但是,上述代码可能会遇到一个问题:当较多时,表头可能会被分成多行(比如有固定的情况),此时我们可能需要在每一行的tr上都初始化Sortable,并且还要考虑行拖拽的情况。但通常我们只允许在同一行内拖拽。因此,如果表头只有一行,上述代码是有效的。如果表头有多行(比如有分组表头),则实现会更复杂,需要分别处理每一行,并且可能需要考虑嵌套的Sortable。但这里我们只考虑单行表头的情况。另外,拖拽时可能需要添加样式以提升体验,比如添加一个类名来改变拖拽时的背景色等,可以通过Sortable的ghostClass等选项来实现。参考引用中的经验:在Vue3中,我们使用nextTick确保在DOM更新后获取元素。同时,注意选择正确的容器元素(这里是`.el-table__header-wrappertheadtr`)。最后,如果表格有固定(fixed),ElementPlus会在表头生成多个表格,此时需要分别处理,但上述示例未考虑固定的情况。如果遇到拖动了的情况,请检查选择器是否正确获取到了表头行(theadtr),以及是否在正确的时机(nextTick)进行初始化。以上代码提供了一个基本的实现根据实际需求可能需要调整。</think>### Vue3 + Element Plus 实现表格拖拽排序指南 #### 核心实现步骤 1. **安装依赖**: ```bash npm install sortablejs --save ``` 2. **组件结构**: ```vue <template> <el-table :data="tableData" border style="width: 100%"> <el-table-column v-for="col in columns" :key="col.prop" :prop="col.prop" :label="col.label" /> </el-table> </template> <script setup> import { ref, onMounted, nextTick } from &#39;vue&#39; import Sortable from &#39;sortablejs&#39; // 定义(顺序可拖拽调整) const columns = ref([ { prop: &#39;date&#39;, label: &#39;日期&#39; }, { prop: &#39;name&#39;, label: &#39;姓名&#39; }, { prop: &#39;address&#39;, label: &#39;地址&#39; } ]) // 表格数据 const tableData = ref([ { date: &#39;2023-01-01&#39;, name: &#39;张三&#39;, address: &#39;北京&#39; }, { date: &#39;2023-01-02&#39;, name: &#39;李四&#39;, address: &#39;上海&#39; } ]) </script> ``` 3. **初始化拖拽**: ```vue <script setup> // ...其他代码 // 关键:初始化拖拽 const initColumnDrag = () => { nextTick(() => { // 获取表头行元素(注意选择器) const headerRow = document.querySelector(&#39;.el-table__header-wrapper tr&#39;) if (!headerRow) return Sortable.create(headerRow, { animation: 300, draggable: &#39;th&#39;, // 限制只能拖动表头单元格 ghostClass: &#39;sortable-ghost&#39;, onEnd: (event) => { const { oldIndex, newIndex } = event // 更新顺序 const newColumns = [...columns.value] const [movedCol] = newColumns.splice(oldIndex, 1) newColumns.splice(newIndex, 0, movedCol) columns.value = newColumns // 这里可以添加保存顺序的逻辑 console.log(&#39;新顺序:&#39;, columns.value.map(c => c.prop)) } }) }) } onMounted(() => initColumnDrag()) </script> ``` 4. **添加拖拽样式**: ```css <style scoped> .sortable-ghost { opacity: 0.7; background: #f0f7ff; border: 1px dashed #409eff; } </style> ``` #### 关键注意事项 1. **正确获取DOM元素**: - 使用 `.el-table__header-wrapper tr` 获取表头行元素[^1] - 必须在 `nextTick` 中初始化,确保DOM渲染完成[^1] 2. **拖拽限制**: - 设置 `draggable: &#39;th&#39;` 限制只能拖动表头单元格 - 避免误操作表格行拖拽 3. **数据更新**: - 拖拽结束后更新数组顺序 - Vue自动响应式更新表格渲染 4. **固定处理**: ```javascript // 排除固定 Sortable.create(headerRow, { filter: &#39;.is-fixed-column&#39;, // 排除固定选择器 draggable: &#39;th:not(.is-fixed-column)&#39; }) ``` #### 完整工作流程 ```mermaid graph TD A[安装Sortable.js] --> B[定义响应式数据] B --> C[渲染Element Table] C --> D[nextTick获取表头行] D --> E[初始化Sortable实例] E --> F[拖拽结束更新顺序] F --> G[Vue响应式更新渲染] ``` #### 实际效果 - 用户可拖动表头调整位置 - 拖拽时有半透明和边框效果 - 顺序变化后表格自动更新 - 新顺序可通过API保存到后端 > **调试提示**:若拖拽无效,检查浏览器控制台是否有错误,并使用 `console.log(headerRow)` 验证DOM元素获取是否正确[^1]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值