当前位置:首页 > VUE

vue实现边框高度拖动

2026-01-22 04:29:51VUE

实现边框高度拖动的核心思路

通过监听鼠标事件(mousedown、mousemove、mouseup)来实现拖动效果。在Vue中结合自定义指令或组件封装更为优雅。

基础实现方案(基于自定义指令)

<template>
  <div class="resizable-box" v-resize:height>
    <div class="resizer"></div>
    <div class="content">可拖动调整高度的区域</div>
  </div>
</template>

<script>
export default {
  directives: {
    resize: {
      inserted(el, binding) {
        const direction = binding.arg || 'height'
        const resizer = el.querySelector('.resizer')

        resizer.style.cursor = direction === 'height' ? 'ns-resize' : 'ew-resize'

        resizer.addEventListener('mousedown', initDrag)

        function initDrag(e) {
          e.preventDefault()
          const startY = e.clientY
          const startHeight = parseInt(document.defaultView.getComputedStyle(el).height, 10)

          function doDrag(e) {
            el.style.height = (startHeight + e.clientY - startY) + 'px'
          }

          function stopDrag() {
            document.removeEventListener('mousemove', doDrag)
            document.removeEventListener('mouseup', stopDrag)
          }

          document.addEventListener('mousemove', doDrag)
          document.addEventListener('mouseup', stopDrag)
        }
      }
    }
  }
}
</script>

<style>
.resizable-box {
  position: relative;
  height: 200px;
  border: 1px solid #ccc;
  overflow: hidden;
}

.resizer {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  height: 10px;
  background-color: #eee;
  cursor: ns-resize;
}

.content {
  padding: 10px;
}
</style>

组件化封装方案

创建可复用的ResizableBox组件:

<!-- ResizableBox.vue -->
<template>
  <div class="resizable-box" :style="{ height: currentHeight + 'px' }">
    <slot></slot>
    <div 
      class="resizer"
      @mousedown="startResize"
    ></div>
  </div>
</template>

<script>
export default {
  props: {
    initialHeight: {
      type: Number,
      default: 200
    }
  },
  data() {
    return {
      currentHeight: this.initialHeight,
      isResizing: false
    }
  },
  methods: {
    startResize(e) {
      this.isResizing = true
      const startY = e.clientY
      const startHeight = this.currentHeight

      const doResize = (e) => {
        if (!this.isResizing) return
        this.currentHeight = startHeight + (e.clientY - startY)
      }

      const stopResize = () => {
        this.isResizing = false
        document.removeEventListener('mousemove', doResize)
        document.removeEventListener('mouseup', stopResize)
      }

      document.addEventListener('mousemove', doResize)
      document.addEventListener('mouseup', stopResize)
    }
  }
}
</script>

<style scoped>
.resizable-box {
  position: relative;
  border: 1px solid #ddd;
  overflow: hidden;
}

.resizer {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  height: 8px;
  background-color: #f0f0f0;
  cursor: ns-resize;
  transition: background-color 0.2s;
}

.resizer:hover {
  background-color: #d0d0d0;
}
</style>

使用组件示例

<template>
  <ResizableBox :initial-height="300">
    <div class="content">
      <h3>可调整高度的区域</h3>
      <p>拖动底部边框调整高度</p>
    </div>
  </ResizableBox>
</template>

<script>
import ResizableBox from './ResizableBox.vue'

export default {
  components: {
    ResizableBox
  }
}
</script>

进阶优化方案

添加最小/最大高度限制和拖动时的视觉反馈:

// 在ResizableBox组件的doResize方法中添加限制
doResize(e) {
  if (!this.isResizing) return
  let newHeight = startHeight + (e.clientY - startY)
  newHeight = Math.max(this.minHeight || 50, newHeight)
  newHeight = Math.min(this.maxHeight || 800, newHeight)
  this.currentHeight = newHeight
}

多方向扩展方案

如果需要同时支持宽度和高度的调整:

<div class="resizer-bottom" @mousedown="startResize('height')"></div>
<div class="resizer-right" @mousedown="startResize('width')"></div>
<div class="resizer-corner" @mousedown="startResize('both')"></div>
startResize(direction) {
  // 根据direction参数处理不同的拖动逻辑
}

性能优化建议

对于频繁的DOM操作,建议使用requestAnimationFrame优化:

vue实现边框高度拖动

function doResize(e) {
  if (!this.isResizing) return
  requestAnimationFrame(() => {
    // 更新高度的逻辑
  })
}

标签: 拖动边框
分享给朋友:

相关文章

vue实现内容拖动

vue实现内容拖动

Vue 实现内容拖动的方法 使用原生 HTML5 拖放 API 在 Vue 中可以利用 HTML5 的拖放 API 实现基本的拖动功能。通过 draggable 属性、dragstart、dragen…

vue实现向上拖动

vue实现向上拖动

Vue 实现向上拖动功能 实现向上拖动功能通常需要结合 Vue 的指令和事件处理,以及原生 JavaScript 的拖拽 API。以下是几种常见的方法: 使用 HTML5 拖放 API 通过 HTM…

vue实现边框特效

vue实现边框特效

Vue 实现边框特效的方法 边框特效可以通过 CSS 动画、伪元素、SVG 或 JavaScript 动态计算来实现。以下是几种常见的实现方式: 使用 CSS 动画实现动态边框 在 Vue 组件的…

vue实现拖动文件移动

vue实现拖动文件移动

Vue 实现文件拖动移动 实现文件拖动移动功能通常涉及 HTML5 的拖放 API 和 Vue 的事件处理。以下是具体实现方法: 基础拖放实现 在 Vue 组件中设置拖放区域并处理相关事件:…

React如何让modal可以被拖动

React如何让modal可以被拖动

实现可拖动Modal的方法 在React中实现可拖动的Modal,可以通过结合HTML5的拖拽API或第三方库如react-draggable来完成。以下是两种常用方法的详细说明: 使用react-…

react native实现拖动

react native实现拖动

React Native 实现拖动功能 使用 PanResponder React Native 提供了 PanResponder API 来处理触摸事件,适合实现拖动功能。以下是一个基本实现示例:…