主要实现的功能如图

简介

    demo中将一个box分成左、右上、右下三个部分,这三个部分都可通过拖拉其边界线而改变各自的大小。有点类似于vsCode等这类软件的布局。

实现方式

    拖动边框改变div的大小,其实本质上就是改变了div样式的宽度或者是高度,用这种思路以实现。

1 设计相应的布局

    template部分的代码

<template>
  <div class="box">
    <div class="left" />
    <div class="y-resize" />
    <div class="right">
      <div class="top" />
      <div class="x-resize" />
      <div class="bottom" />
    </div>
  </div>
</template>

这里需要注意的是,x和y轴的两个分隔线并不能理解为简单的border,而是理解为两个div。

2 添加布局的样式

    为各个部分简要添加了一点样式。

<style lang="less" scoped>
.box{
  width: 100%;
  height: 100%;
  border: 1px #056768 solid;
  border-radius: 10px;
  .left,.y-resize,.right{
    float: left;
    overflow: hidden;
  }
  .left{
    width: calc(20% - 10px);
    height: 100%;
    background: #A0CFFF;
    border-radius: 10px 0 0 10px;
  }
  .y-resize{
    width: 10px;
    height: 100%;
    background: #C0C4CC;
    cursor: w-resize;
  }
  .right{
    width: 80%;
    height: 100%;
    .top,.bottom{
      overflow: hidden;
    }
    .top{
      height: calc(20% - 0.6vh);
      background:  #C6E2FF;
      border-radius: 0 10px 0 0;
    }
    .x-resize{
      height: 0.6vh;
      background: #C0C4CC;
      cursor: s-resize;
      position: relative;
    }
    .bottom{
      height: 80%;
      background: #ECF5FF;
      border-radius: 0 0 10px 0;
    }
  }
}
</style>

3 JS部分对鼠标拖动事件的处理

    在mouted函数中调用处理x和y轴拖动的 以下代码中添加了对应的注释,几乎可不用修改,照搬即可实现。

<script>
export default {
  data () {
    return {
    }
  },
  mounted () {
    this.handleYResize()
    this.handleXResize()
  },
  methods: {
    handleYResize () {
      const box = document.getElementsByClassName('box')
      const left = document.getElementsByClassName('left')
      const resize = document.getElementsByClassName('y-resize')
      const right = document.getElementsByClassName('right')
      for (let i = 0; i < resize.length; i++) {
        // 鼠标按下事件
        resize[i].onmousedown = function (e) {
          // 颜色改变提醒
          resize[i].style.background = '#818181'
          const startX = e.clientX
          resize[i].left = resize[i].offsetLeft
          // 鼠标拖动事件
          document.onmousemove = function (e) {
            const endX = e.clientX
            let moveLen = resize[i].left + (endX - startX) // (endX-startX)=移动的距离。resize[i].left+移动的距离=左侧最终的高度
            const maxT = box[i].clientWidth - resize[i].offsetWidth // 容器宽度 - 左边区域的宽度 = 右边区域的宽度
            if (moveLen < 30) moveLen = 30 // left最小宽度度为30px
            if (moveLen > maxT - 30) moveLen = maxT - 30 // right最小宽度度为30px

            resize[i].style.left = moveLen // 设置left区域的宽度
            for (let j = 0; j < left.length; j++) {
              left[j].style.width = moveLen + 'px'
              right[j].style.width = (box[i].clientWidth - moveLen - 10) + 'px'
            }
          }
          // 鼠标松开事件
          document.onmouseup = function (evt) {
            // 颜色恢复
            resize[i].style.background = '#C0C4CC'
            document.onmousemove = null
            document.onmouseup = null
            resize[i].releaseCapture && resize[i].releaseCapture() // 当你不在需要继续获得鼠标消息就要应该调用ReleaseCapture()释放掉
          }
          resize[i].setCapture && resize[i].setCapture() // 该函数在属于当前线程的指定窗口里设置鼠标捕获
          return false
        }
      }
    },
    handleXResize () {
      const box = document.getElementsByClassName('box')
      const top = document.getElementsByClassName('top')
      const resize = document.getElementsByClassName('x-resize')
      const bottom = document.getElementsByClassName('bottom')
      for (let i = 0; i < resize.length; i++) {
        // 鼠标按下事件
        resize[i].onmousedown = function (e) {
          // 颜色改变提醒
          resize[i].style.background = '#818181'
          const startY = e.clientY
          resize[i].top = top[i].offsetHeight
          // 鼠标拖动事件
          document.onmousemove = function (e) {
            const endY = e.clientY
            let moveLen = resize[i].top + (endY - startY) // (endY-startY)=移动的距离。resize[i].top+移动的距离=上部最终的高度
            const maxT = box[i].clientHeight - resize[i].offsetHeight // 容器宽度 - 左边区域的宽度 = 右边区域的宽度
            if (moveLen < 30) moveLen = 30 // top最小高度度为30px
            if (moveLen > maxT - 30) moveLen = maxT - 30 // bottom最小高度度为30px

            resize[i].style.height = moveLen // 设置top区域的高度
            for (let j = 0; j < top.length; j++) {
              top[j].style.height = moveLen + 'px'
              bottom[j].style.height = (box[i].clientHeight - moveLen - 10) + 'px'
            }
          }
          // 鼠标松开事件
          document.onmouseup = function (evt) {
            // 颜色恢复
            resize[i].style.background = '#C0C4CC'
            document.onmousemove = null
            document.onmouseup = null
            resize[i].releaseCapture && resize[i].releaseCapture() // 当你不在需要继续获得鼠标消息就要应该调用ReleaseCapture()释放掉
          }
          resize[i].setCapture && resize[i].setCapture() // 该函数在属于当前线程的指定窗口里设置鼠标捕获
          return false
        }
      }
    }
  }
}
</script>

 

Logo

前往低代码交流专区

更多推荐