Vue3实现自适应拖拽两边伸缩

504 阅读1分钟

前言

实现便捷拖拽功能,通过轻松拖动操作,让表格与地图之间的界线自动调整,使得两侧宽度自适应

基础代码

<script setup lang="ts">
import { ref } from 'vue'
const leftPaneWidth = ref(200)
<template>
  <div class="box">
    <div class="left" :style="{ width: `${leftPaneWidth}px` }"></div>

    <div class="resize" ></div>

    <div class="right" :style="{ width: `calc(100% - ${leftPaneWidth}px)` }"></div>
  </div>
</template>

<style scoped>
.box {
  width: 1200px;
  height: 600px;
  border: 1px solid red;
  display: flex;
}
.left {
  height: 100%;
  background: #333;
}
.right {
  height: 100%;
  background: #ccc;
}
.resize {
  width: 5px;
  height: 100%;
  background: red;
  cursor: ew-resize;
}
</style>

运行之后:

使用例子

组件源码

<template>
  <div class="resize" title="收缩侧边栏" @mousedown="startResize"></div>
</template>

<script lang="ts" setup>
interface Props {
  leftPaneWidth?: number // 左边栏基础宽度
  rightPaneWidth?: number // 右边栏基础宽度
}
const props = withDefaults(defineProps<Props>(), {
  leftPaneWidth: 0,
  rightPaneWidth: 0,
})
const emit = defineEmits(['update:resizeWidth']) // 更新左或者右宽度

const isResizing = ref<boolean>(false)
const startX = ref<number>(0) // 拖拽距离
const width = ref<number>(props.leftPaneWidth || props.rightPaneWidth) // 设置基础宽度

// 鼠标点击触发
const startResize = (event: MouseEvent) => {
  isResizing.value = true
  // 开始位置
  startX.value = event.clientX
  document.addEventListener('mousemove', resize)
  document.addEventListener('mouseup', stopResize)
}

// 鼠标移动监控函数
const resize = (event: MouseEvent) => {
  if (isResizing.value) {
    const deltaX = event.clientX - startX.value
    if (props.leftPaneWidth) {
      width.value += deltaX
    } else {
      width.value -= deltaX
    }
    emit('update:resizeWidth', width.value)
    startX.value = event.clientX
  }
}

// 注销监听鼠标事件函数
const stopResize = () => {
  isResizing.value = false
  document.removeEventListener('mousemove', resize)
  document.removeEventListener('mouseup', stopResize)
}
</script>
<style lang="scss" scoped>
/*拖拽区div样式*/
.resize {
  cursor: col-resize;
  width: 10px;
  height: 100%;
}
</style>