当前位置:首页 > VUE

vue实现表格拖动列宽

2026-02-09 20:29:16VUE

实现表格列宽拖动的核心思路

通过监听鼠标事件(mousedown、mousemove、mouseup)动态修改列宽度。需要处理表头单元格的拖拽手柄,计算鼠标移动距离并更新列宽。

基本实现步骤

创建可拖拽的表头单元格,添加拖拽手柄元素:

<template>
  <table>
    <thead>
      <tr>
        <th v-for="(col, index) in columns" :key="index">
          <div class="header-content">
            {{ col.title }}
            <div 
              class="resize-handle"
              @mousedown="startResize(index, $event)"
            ></div>
          </div>
        </th>
      </tr>
    </thead>
    <tbody>
      <!-- 表格数据行 -->
    </tbody>
  </table>
</template>

添加CSS样式确保拖拽手柄可见:

.resize-handle {
  width: 5px;
  height: 100%;
  background: #ccc;
  cursor: col-resize;
  position: absolute;
  right: 0;
  top: 0;
}

th {
  position: relative;
  padding-right: 15px; /* 为手柄留空间 */
}

实现拖拽逻辑的JavaScript部分:

vue实现表格拖动列宽

export default {
  data() {
    return {
      columns: [
        { title: '列1', width: 150 },
        { title: '列2', width: 200 }
      ],
      isResizing: false,
      currentColumn: null,
      startX: 0,
      startWidth: 0
    }
  },
  methods: {
    startResize(index, e) {
      this.isResizing = true
      this.currentColumn = index
      this.startX = e.clientX
      this.startWidth = this.columns[index].width

      document.addEventListener('mousemove', this.handleResize)
      document.addEventListener('mouseup', this.stopResize)
    },
    handleResize(e) {
      if (!this.isResizing) return
      const dx = e.clientX - this.startX
      this.columns[this.currentColumn].width = this.startWidth + dx
    },
    stopResize() {
      this.isResizing = false
      document.removeEventListener('mousemove', this.handleResize)
      document.removeEventListener('mouseup', this.stopResize)
    }
  }
}

性能优化建议

使用CSS transforms代替直接修改宽度减少重排:

handleResize(e) {
  if (!this.isResizing) return
  const dx = e.clientX - this.startX
  this.$refs.table.querySelectorAll('th')[this.currentColumn].style.width = 
    `${this.startWidth + dx}px`
}

添加防抖处理避免频繁更新:

vue实现表格拖动列宽

import { debounce } from 'lodash'

methods: {
  handleResize: debounce(function(e) {
    // 处理逻辑
  }, 16) // 约60fps
}

完整组件示例

结合表格数据的完整组件实现:

<template>
  <div class="resizable-table">
    <table ref="table">
      <thead>
        <tr>
          <th 
            v-for="(col, index) in columns" 
            :key="index"
            :style="{ width: col.width + 'px' }"
          >
            <div class="header-content">
              {{ col.title }}
              <div 
                class="resize-handle"
                @mousedown="startResize(index, $event)"
              ></div>
            </div>
          </th>
        </tr>
      </thead>
      <tbody>
        <tr v-for="(row, rowIndex) in data" :key="rowIndex">
          <td 
            v-for="(col, colIndex) in columns" 
            :key="colIndex"
            :style="{ width: columns[colIndex].width + 'px' }"
          >
            {{ row[col.key] }}
          </td>
        </tr>
      </tbody>
    </table>
  </div>
</template>

边界情况处理

防止列宽过小:

handleResize(e) {
  if (!this.isResizing) return
  const dx = e.clientX - this.startX
  const newWidth = Math.max(30, this.startWidth + dx) // 最小30px
  this.columns[this.currentColumn].width = newWidth
}

处理表格滚动情况:

startResize(index, e) {
  // 获取表格相对于视口的位置
  const rect = this.$refs.table.getBoundingClientRect()
  this.startX = e.clientX - rect.left
  // 其他逻辑...
}

标签: 拖动表格
分享给朋友:

相关文章

css制作表格

css制作表格

使用HTML和CSS创建表格 HTML中的<table>元素用于创建表格,结合CSS可以调整样式。以下是一个基础示例: <table> <tr> &l…

vue实现数据拖动

vue实现数据拖动

Vue 实现数据拖动 在 Vue 中实现数据拖动通常涉及 HTML5 的拖放 API 或第三方库(如 vuedraggable)。以下是两种常见方法: 使用 HTML5 拖放 API 设置拖拽元素…

css 制作表格

css 制作表格

CSS 制作表格的方法 使用 CSS 制作表格可以通过多种方式实现,包括原生 HTML 表格样式、Flexbox 布局或 Grid 布局。以下是几种常见的方法: 原生 HTML 表格样式 HTML…

css表格制作表格

css表格制作表格

CSS 表格制作方法 基础表格结构 使用HTML的<table>标签创建表格框架,搭配<tr>(行)、<td>(单元格)和<th>(表头)标签: &l…

css表格制作

css表格制作

CSS表格制作方法 使用CSS创建表格可以通过多种方式实现,以下是常见的几种方法: 使用HTML原生表格标签结合CSS样式 <table class="styled-table">…

vue实现简单表格

vue实现简单表格

使用 Vue 实现简单表格 Vue 提供了多种方式实现表格功能,以下是基于 Vue 3 的两种常见方法: 基础表格实现 通过 v-for 指令循环渲染表格数据: <template&…