vue3+ts 拖拽容器边缘,改变容器宽度和高度

例如:我们的代码编辑器

终端与代码区,可以纵向拖拽,改变两个容器高度

目录与代码区可以横向拖拽,改变两个容器宽度

本文使用vue3+ts+tailwindcss,把横向纵向整合在一起写了,也可以分开使用
utils目录下新建一个drag.ts文件

import { Ref } from 'vue'

interface ResizeOptions {
  rightRef?: Ref<HTMLElement | null>
  bottomRef?: Ref<HTMLElement | null>
}

const useResize = ({ rightRef, bottomRef }: ResizeOptions) => {
  let startX = 0
  let startWidth = 0
  let isHorizonResizing = false
  let startY = 0
  let startHeight = 0
  let isVerticalResizing = false

  const startHorizonResize = (event: MouseEvent) => {
    if (rightRef && rightRef.value) {
      startX = event.clientX
      startWidth = rightRef.value.offsetWidth
      isHorizonResizing = true

      window.addEventListener('mousemove', doHorizonResize)
      window.addEventListener('mouseup', stopHorizonResize)
    }
  }

  const doHorizonResize = (event: MouseEvent) => {
    if (isHorizonResizing && rightRef && rightRef.value) {
      const deltaX = event.clientX - startX
      rightRef.value.style.width = startWidth - deltaX + 'px'
    }
  }

  const stopHorizonResize = () => {
    isHorizonResizing = false
    window.removeEventListener('mousemove', doHorizonResize)
    window.removeEventListener('mouseup', stopHorizonResize)
  }

  const startVerticalResize = (event: MouseEvent) => {
    if (bottomRef && bottomRef.value) {
      startY = event.clientY
      startHeight = bottomRef.value.offsetHeight
      isVerticalResizing = true
      window.addEventListener('mousemove', doVerticalResize)
      window.addEventListener('mouseup', stopVerticalResize)
    }
  }

  const doVerticalResize = (event: MouseEvent) => {
    if (isVerticalResizing && bottomRef && bottomRef.value) {
      const deltaY = event.clientY - startY
      bottomRef.value.style.height = startHeight - deltaY + 'px'
    }
  }

  const stopVerticalResize = () => {
    isVerticalResizing = false
    window.removeEventListener('mousemove', doVerticalResize)
    window.removeEventListener('mouseup', stopVerticalResize)
  }

  return {
    startHorizonResize,
    startVerticalResize,
  }
}

export default useResize

使用

<template>
  <div class="h-full w-full flex">
    <div class="flex-1 h-full min-w-[100px] w-[300px] bg-[#c1ddfb]"></div>
    <div class="cursor-col-resize h-full w-[2px] bg-[#000]" @mousedown.stop.prevent="startHorizonResize"></div>
    <div class="h-full w-[calc(100%-300px)] min-w-[500px]" ref="refRight">
      <div class="w-full h-full flex flex-col">
        <div class="flex-1 bg-[#ebbbdd] h-[400px] min-h-[100px] w-full"></div>
        <div class="cursor-row-resize h-[2px] bg-[#333] w-full" @mousedown.stop.prevent="startVerticalResize"></div>
        <div class="bg-[#c0eaab] h-[calc(100%-400px)] min-h-[100px] w-full" ref="refBottom"></div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'
import useResize from '@/utils/drag'

const refRight = ref<HTMLElement | null>(null)
const refBottom = ref<HTMLElement | null>(null)

const { startHorizonResize, startVerticalResize } = useResize({ rightRef: refRight, bottomRef: refBottom })
</script>

<style scoped></style>

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
可以使用`vue-draggable-resizable`插件来实现拖动调整左右两侧div的宽度。 首先在项目中安装`vue-draggable-resizable`: ``` npm install vue-draggable-resizable --save ``` 然后在需要使用的组件中引入: ```javascript import VueDraggableResizable from 'vue-draggable-resizable' import 'vue-draggable-resizable/dist/VueDraggableResizable.css' ``` 接着在组件中使用`vue-draggable-resizable`: ```html <template> <div> <vue-draggable-resizable :w="leftWidth" :h="height" :x="0" :y="0" :min-width="minWidth" :max-width="maxWidth" :parent="true" :active="true" :grid="[1, 1]" :handles="['e']" @resize="onResize" > <div class="left"></div> </vue-draggable-resizable> <div class="divider"></div> <div class="right"></div> </div> </template> <script> import VueDraggableResizable from 'vue-draggable-resizable' import 'vue-draggable-resizable/dist/VueDraggableResizable.css' export default { components: { VueDraggableResizable }, data() { return { leftWidth: 200, height: 500, minWidth: 100, maxWidth: 400 } }, methods: { onResize() { // 当左侧div宽度改变时触发 } } } </script> ``` 在上面的代码中,我们使用了`vue-draggable-resizable`组件来实现拖动调整左侧div的宽度。具体的参数和事件如下: - `w`:左侧div的宽度 - `h`:左侧div的高度 - `x`:左侧div的x坐标 - `y`:左侧div的y坐标 - `min-width`:左侧div的最小宽度 - `max-width`:左侧div的最大宽度 - `parent`:是否限制在父元素内 - `active`:是否活动状态 - `grid`:拖拽的网格大小 - `handles`:拖拽的手柄位置 - `@resize`:左侧div改变宽度时触发的事件 通过设置`handles`为`['e']`,表示只能横向拖动调整宽度,而不能改变高度。当左侧div的宽度改变时,会触发`@resize`事件,在事件处理函数中可以实现相应的逻辑。 最后,为了实现左右两侧div并排显示,需要在样式中设置: ```css .left { float: left; height: 100%; background-color: #f0f0f0; } .right { float: left; height: 100%; width: calc(100% - 200px); background-color: #e0e0e0; } .divider { float: left; height: 100%; width: 10px; background-color: #d0d0d0; } ``` 这样就可以实现拖动调整左右两侧div的宽度了。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值