拉伸元素设置组件高度和宽度

lishihuan大约 1 分钟

拉伸元素设置组件高度和宽度

  • 效果图

通过 拉伸设置元素的高度和宽度

image-20231020152405300
image-20231020152405300

1. 添加拖拽手柄

<div class="resize-handle horizontal" :class="'horizontal_'+rowIndex" @mousedown="startResize($event, 'horizontal',rowIndex,colIndex)" title="左右拖动拉伸表格宽度"> </div>
    <!-- 垂直方向拖拽拉伸 -->
    <div class="resize-handle vertical" :class="'vertical_'+colIndex" @mousedown="startResize($event, 'vertical',rowIndex,colIndex)" title="上下拖动拉伸表格高度"> </div>

2. js实现

export default {
  data() {
    return {
      isDragging: false,
      resizeData: null,
      currentRowIndex: null,
      currentColIndex: null,
    };
  },
  mounted() {
    document.addEventListener('mousemove', this.onMouseMove);
    document.addEventListener('mouseup', this.onMouseUp);
  },
  beforeDestroy() {
    document.removeEventListener('mousemove', this.onMouseMove);
    document.removeEventListener('mouseup', this.onMouseUp);
  },
  methods: {
    startResize(event, direction, rowIndex, colIndex) {
      const initialClientX = event.clientX;
      const initialClientY = event.clientY;
      const cell = event.target.parentNode;

      this.isDragging = true;
      this.resizeData = {
        initialClientX,
        initialClientY,
        initialWidth: cell.offsetWidth,
        initialHeight: cell.offsetHeight,
        direction,
        cell,
      };
      this.currentRowIndex = rowIndex;
      this.currentColIndex = colIndex;
    },
    onMouseMove(event) {
      if (!this.isDragging || !this.resizeData) return;

      const offsetX = event.clientX - this.resizeData.initialClientX;
      const offsetY = event.clientY - this.resizeData.initialClientY;
      const cell = this.resizeData.cell;

      if (this.resizeData.direction === 'horizontal') {
        const newWidth = this.resizeData.initialWidth + offsetX;
        cell.style.width = `${newWidth}px`;
      } else if (this.resizeData.direction === 'vertical') {
        const newHeight = this.resizeData.initialHeight + offsetY;
        cell.style.height = `${newHeight}px`;
      }
    },
    onMouseUp() {
      if (!this.isDragging || !this.resizeData) return;

      const rowIndex = this.currentRowIndex;
      const colIndex = this.currentColIndex;

      // 与保存的索引匹配时才处理业务逻辑
      if (rowIndex !== null && colIndex !== null) {
        const item = this.parentWidget.rows[rowIndex].cols[colIndex];
        if (this.resizeData.direction === 'horizontal') {
          item.options.cellWidth = this.resizeData.cell.style.width;
        } else if (this.resizeData.direction === 'vertical') {
          item.options.cellHeight = this.resizeData.cell.style.height;
        }
      }

      this.isDragging = false;
      this.resizeData = null;
      this.currentRowIndex = null;
      this.currentColIndex = null;
    },
  },
};

<style lang="scss" scoped>
    .resize-handle {
        position: absolute;
        width: 0;
        height: 0;
        background: #409EFF;
        z-index: 9;
        /* 水平拖拽权柄*/
        &.horizontal {
            top: 0;
            right: -5px;
            cursor: ew-resize;
            &.horizontal_0{
                width: 10px;
                height: 10px;
            }
        }
        /* 垂直拖拽权柄*/
        &.vertical {
            cursor: ns-resize;
            bottom: -2px;
            left: -2px;
            &.vertical_0{
                width: 10px;
                height: 10px;
            }
        }
    }
</style>