当前位置:首页 > VUE

vue实现div拉伸

2026-02-09 13:15:02VUE

实现 div 拉伸的基本思路

在 Vue 中实现 div 拉伸功能,通常需要结合鼠标事件(如 mousedownmousemovemouseup)和动态样式绑定。核心是通过监听鼠标移动来调整 div 的宽度或高度。

水平拉伸 div 的代码示例

以下是一个实现 div 水平拉伸的 Vue 组件示例:

<template>
  <div class="container">
    <div class="left-panel" :style="{ width: leftWidth + 'px' }">左侧内容</div>
    <div class="resize-handle" @mousedown="startResize"></div>
    <div class="right-panel">右侧内容</div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      leftWidth: 200,
      isResizing: false
    }
  },
  methods: {
    startResize(e) {
      this.isResizing = true
      document.addEventListener('mousemove', this.resize)
      document.addEventListener('mouseup', this.stopResize)
    },
    resize(e) {
      if (this.isResizing) {
        this.leftWidth = e.clientX
      }
    },
    stopResize() {
      this.isResizing = false
      document.removeEventListener('mousemove', this.resize)
      document.removeEventListener('mouseup', this.stopResize)
    }
  }
}
</script>

<style>
.container {
  display: flex;
  height: 100vh;
}
.left-panel {
  background: #f0f0f0;
}
.resize-handle {
  width: 10px;
  background: #ccc;
  cursor: col-resize;
}
.right-panel {
  flex: 1;
  background: #e0e0e0;
}
</style>

垂直拉伸 div 的实现

要实现垂直拉伸,只需调整相关逻辑和样式:

<template>
  <div class="vertical-container">
    <div class="top-panel" :style="{ height: topHeight + 'px' }">顶部内容</div>
    <div class="resize-handle-vertical" @mousedown="startResize"></div>
    <div class="bottom-panel">底部内容</div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      topHeight: 200,
      isResizing: false
    }
  },
  methods: {
    startResize(e) {
      this.isResizing = true
      document.addEventListener('mousemove', this.resize)
      document.addEventListener('mouseup', this.stopResize)
    },
    resize(e) {
      if (this.isResizing) {
        this.topHeight = e.clientY
      }
    },
    stopResize() {
      this.isResizing = false
      document.removeEventListener('mousemove', this.resize)
      document.removeEventListener('mouseup', this.stopResize)
    }
  }
}
</script>

<style>
.vertical-container {
  display: flex;
  flex-direction: column;
  height: 100vh;
}
.top-panel {
  background: #f0f0f0;
}
.resize-handle-vertical {
  height: 10px;
  background: #ccc;
  cursor: row-resize;
}
.bottom-panel {
  flex: 1;
  background: #e0e0e0;
}
</style>

双向拉伸实现

要实现同时支持水平和垂直拉伸的 div:

<template>
  <div class="resizable-box" 
       :style="{ width: width + 'px', height: height + 'px' }">
    <div class="content">可拉伸内容</div>
    <div class="resize-handle-right" @mousedown="startResize('right')"></div>
    <div class="resize-handle-bottom" @mousedown="startResize('bottom')"></div>
    <div class="resize-handle-corner" @mousedown="startResize('both')"></div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      width: 300,
      height: 200,
      isResizing: false,
      resizeDirection: null,
      startX: 0,
      startY: 0,
      startWidth: 0,
      startHeight: 0
    }
  },
  methods: {
    startResize(direction, e) {
      this.resizeDirection = direction
      this.isResizing = true
      this.startX = e.clientX
      this.startY = e.clientY
      this.startWidth = this.width
      this.startHeight = this.height

      document.addEventListener('mousemove', this.doResize)
      document.addEventListener('mouseup', this.stopResize)
    },
    doResize(e) {
      if (this.isResizing) {
        if (this.resizeDirection === 'right' || this.resizeDirection === 'both') {
          this.width = this.startWidth + (e.clientX - this.startX)
        }
        if (this.resizeDirection === 'bottom' || this.resizeDirection === 'both') {
          this.height = this.startHeight + (e.clientY - this.startY)
        }
      }
    },
    stopResize() {
      this.isResizing = false
      document.removeEventListener('mousemove', this.doResize)
      document.removeEventListener('mouseup', this.stopResize)
    }
  }
}
</script>

<style>
.resizable-box {
  position: relative;
  border: 1px solid #ccc;
  background: #f8f8f8;
}
.content {
  padding: 20px;
}
.resize-handle-right {
  position: absolute;
  right: 0;
  top: 0;
  width: 5px;
  height: 100%;
  cursor: col-resize;
}
.resize-handle-bottom {
  position: absolute;
  bottom: 0;
  left: 0;
  width: 100%;
  height: 5px;
  cursor: row-resize;
}
.resize-handle-corner {
  position: absolute;
  right: 0;
  bottom: 0;
  width: 10px;
  height: 10px;
  cursor: nwse-resize;
}
</style>

性能优化建议

在实现拉伸功能时,频繁的 DOM 操作可能影响性能。可以考虑以下优化措施:

  • 使用 requestAnimationFrame 替代直接的样式更新
  • 添加防抖或节流处理
  • 避免在 mousemove 事件中进行复杂的计算
  • 在组件销毁时移除事件监听器
// 在组件中添加
beforeDestroy() {
  document.removeEventListener('mousemove', this.doResize)
  document.removeEventListener('mouseup', this.stopResize)
}

注意事项

  • 确保在组件销毁时移除事件监听器,避免内存泄漏
  • 考虑添加最小和最大尺寸限制
  • 移动端实现可能需要处理触摸事件
  • 复杂的布局可能需要更精细的控制逻辑

vue实现div拉伸

标签: vuediv
分享给朋友:

相关文章

vue怎么实现数据检测

vue怎么实现数据检测

Vue 数据检测的实现方式 Vue 通过响应式系统实现数据检测,核心机制基于 Object.defineProperty(Vue 2)或 Proxy(Vue 3)。以下是具体实现方法: 基于 Vu…

vue实现visual

vue实现visual

Vue 实现可视化(Visual)的常见方法 在 Vue 中实现可视化通常涉及数据可视化库的集成,以下是几种主流方案: 使用 ECharts ECharts 是一个强大的 JavaScript…

vue实现节流

vue实现节流

vue实现节流的方法 在Vue中实现节流(throttle)功能,通常用于限制高频事件的触发频率,例如滚动、输入或按钮点击。以下是几种常见的实现方式: 使用Lodash的throttle函数 安装L…

vue 实现视频

vue 实现视频

Vue 实现视频播放功能 使用 Vue 实现视频播放功能可以通过 HTML5 的 <video> 标签或第三方库(如 video.js)来实现。以下是两种常见的方法: 使用 HTML5…

vue 实现评分

vue 实现评分

Vue 实现评分功能 在 Vue 中实现评分功能可以通过多种方式完成,包括使用第三方组件库或自定义实现。以下是两种常见的方法: 使用第三方组件库(如 Element UI) Element UI…

vue实现列表

vue实现列表

Vue 实现列表的方法 在 Vue 中实现列表渲染通常使用 v-for 指令,可以动态生成多个元素。以下是几种常见的实现方式: 基础列表渲染 使用 v-for 遍历数组,生成列表项。v-for 需要…