<template>
  <div class='container'>
    <div class='top' :style='topStyle' ref='top'></div>
    <div class='divider' @mousedown='startDrag'></div>
    <div class='bottom' :style='bottomStyle' ref='bottom'></div>
  </div>
</template>
<script>
import { ref, reactive } from 'vue'

export default {
  setup() {
    const container = ref(null)
    const top = ref(null)
    const bottom = ref(null)
    const dragging = reactive({
      active: false,
      startY: 0,
      startHeight: 0
    })

    const startDrag = e => {
      dragging.active = true
      dragging.startY = e.clientY
      dragging.startHeight = top.value.offsetHeight
    }

    const stopDrag = () => {
      dragging.active = false
    }

    const handleDrag = e => {
      if (!dragging.active) return
      const delta = e.clientY - dragging.startY
      top.value.style.height = `${dragging.startHeight + delta}px`
    }

    const topStyle = { height: '50%' }
    const bottomStyle = { height: '50%' }

    return {
      container,
      top,
      bottom,
      dragging,
      startDrag,
      stopDrag,
      handleDrag,
      topStyle,
      bottomStyle
    }
  },
  mounted() {
    document.addEventListener('mousemove', this.handleDrag)
    document.addEventListener('mouseup', this.stopDrag)
  },
  unmounted() {
    document.removeEventListener('mousemove', this.handleDrag)
    document.removeEventListener('mouseup', this.stopDrag)
  }
}
</script>
<style scoped>
.container {
  position: relative;
  height: 100%;
}

.top {
  background-color: #f0f0f0;
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: auto;
  overflow: auto;
}

.divider {
  background-color: #ddd;
  position: absolute;
  top: 50%;
  left: 0;
  right: 0;
  height: 10px;
  cursor: ns-resize;
  z-index: 1;
}

.bottom {
  background-color: #f0f0f0;
  position: absolute;
  top: auto;
  left: 0;
  right: 0;
  bottom: 0;
  overflow: auto;
}
</style>
<p>该示例使用 Vue3 的 'ref' 和 'reactive' 创建响应式变量。通过 'ref' 获取组件 DOM 元素,并将其暴露给模板。使用 'reactive' 创建一个包含 'active'、'startY' 和 'startHeight' 的对象,用于控制拖动操作。</p>
<p>模板中渲染三个 'div' 元素,分别代表顶部组件、分割条和底部组件。使用 ':style' 绑定顶部和底部组件的高度,以便在拖动分割条时动态调整高度。</p>
<p>分割条元素添加 'mousedown' 事件监听器,在用户开始拖动时调用 'startDrag' 方法。该方法设置 'dragging' 对象的属性,记录鼠标位置和顶部组件的初始高度。</p>
<p>添加 'mouseup' 事件监听器,在用户停止拖动时调用 'stopDrag' 方法,将 'dragging.active' 设置为 'false'。</p>
<p>添加 'mousemove' 事件监听器,在用户拖动时调用 'handleDrag' 方法。该方法检查 'dragging.active' 是否为 'true',如果为 'true',计算鼠标位置相对于初始位置的偏移量,并将其添加到顶部组件的初始高度中,以获得新的高度。</p>
<p>最后,定义 CSS 样式,设置组件的外观和布局。</p>
Vue3 实现上下两个组件拖动分割条代码示例

原文地址: https://www.cveoy.top/t/topic/nTGm 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录