使用VUE3+Element Plus 实现动态表格

本文介绍如何使用Vue的el-table组件,通过数据驱动的方式实现表格的列头根据prop配置动态渲染,并演示了如何调整表头顺序及自定义表头显示。实例代码展示了如何利用`tableData`和`tableHeader`配合使用,实现灵活的数据展示。

他的原理是,只要el-table表格数据的键(tableData.list的键),与遍历时表头的prop对应上(tableHeader的值),就可将数据渲染上去。
如果需要更改表头顺序,只需要对tableHeader进行排序即可。
(当然,跟后端关系好,可以让后端直接返回表头,前端仅需遍历即可)
预览效果:
动态表格

整体代码如下

<template>
  <el-table :data="tableData.list">
    <el-table-column
      v-for="(item, index) in tableHeader"
      :key="index"
      :label="item"
      :prop="item"
    ></el-table-column>
  </el-table>
</template>

<script>
import { reactive } from "vue";
export default {
  name: "APP",
  setup() {
    // 表格展示数据
    let tableData = reactive({
      list: [
        {
          "06/20": "34.0",
          "06/21": "23.0",
          "06/29": "1.0",
        },
        {
          "06/20": "24.0",
          "06/21": "24.0",
          "06/29": "2.0",
        },
        {
          "06/20": "35.0",
          "06/21": "35.0",
          "06/29": "3.0",
        },
        {
          "06/20": "",
          "06/21": "",
          "06/29": "",
        },
        {
          "06/20": "23.0",
          "06/21": "23.0",
          "06/29": "5.0",
        },
        {
          "06/20": "269.0",
          "06/21": "256.0",
          "06/29": "36.0",
        },
      ],
    });
    tableData.list.forEach((item, key) => {
      item["name"] = "第" + (key + 1) + "行";
    });
    // 获取表头
    const tableHeader = Object.keys(tableData.list[0]);

    return {
      tableData,
      tableHeader,
    };
  },
};
</script>

也可以将表头的键值对取出来,前端自定义表头的中文名称,达到这个效果
在这里插入图片描述

<template>
  <el-table :data="tableData.list">
    <el-table-column
      v-for="(item, index) in tableHeader"
      :key="index"
      :label="item.value"
      :prop="item.key"
    >
    </el-table-column>
  </el-table>
</template>

<script>
import { reactive } from "vue";
export default {
  name: "APP",
  setup() {
    // 表格展示数据
    let tableData = reactive({
      list: [
        {
          "06/20": "34.0",
          "06/21": "23.0",
          "06/29": "1.0",
        },
        {
          "06/20": "24.0",
          "06/21": "24.0",
          "06/29": "2.0",
        },
        {
          "06/20": "35.0",
          "06/21": "35.0",
          "06/29": "3.0",
        },
        {
          "06/20": "",
          "06/21": "",
          "06/29": "",
        },
        {
          "06/20": "23.0",
          "06/21": "23.0",
          "06/29": "5.0",
        },
        {
          "06/20": "269.0",
          "06/21": "256.0",
          "06/29": "36.0",
        },
      ],
    });
    tableData.list.forEach((item, key) => {
      item["name"] = "第" + (key + 1) + "行";
    });
    // 生成表头
    const tableHeader = generateHeader();
    function generateHeader() {
      const result = [
        {
          key: "name",
          value: "表头",
        },
      ];
      for (let item in tableData.list[0]) {
        if (item !== "name") {
          const obj = {
            key: item,
            value: item,
          };
          result.push(obj);
        }
      }
      return result;
    }

    return {
      tableData,
      tableHeader,
    };
  },
};
</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.模板部分(使用ElementPlusel-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]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值