Bootstrap

vue中实现拖动效果改变页面两侧盒子宽度

前言

找了许多关于鼠标拖动改变页面两个盒子宽度的方式,感觉效果都不是很理想,所以记录一下。


一.封装 vue 自定义指令的方式

代码如下(示例):

import Vue from 'vue'

import { EventListener } from '@/utils/index'
//引入 EventListener 自定义监听事件方法,写法在我另一篇文章

Vue.directive('elResize', {
  inserted(el, binding, vnode) {
    const container = el.parentNode

    const left = container.children[0]
    const right = container.children[container.children.length - 1]

    let documentMousemoveEvent = null
    let documentMouseupEvent = null
    el.addEventListener('mousedown', function (e)  {
      container.style.userSelect = 'none'
      container.style.cursor = 'col-resize'
      let startX = e.clientX
      let containerOffsetWidth = parseInt(getComputedStyle(container).width)
      let elOffsetLeft = el.offsetLeft
      documentMousemoveEvent = EventListener.listen(document, 'mousemove', mousemoveEvent => {
        var endX = mousemoveEvent.clientX
        var moveLen = elOffsetLeft + (endX - startX) // (endx-startx)=移动的距离。
        var maxT = containerOffsetWidth - el.offsetWidth // 容器宽度 - 左边区域的宽度 = 右边区域的宽度
        if (moveLen < 700) moveLen = 700 // 左边区域的最小宽度为700px
        if (moveLen > maxT - 280) moveLen = maxT - 280 //右边区域最小宽度为280px
        el.style.left = moveLen
        left.style.width = moveLen + 'px'
        right.style.width = (containerOffsetWidth - moveLen - 10) + 'px'
      })

      documentMouseupEvent = EventListener.listen(document, 'mouseup', mouseupEvent => {
        container.style.userSelect = 'unset'
        container.style.cursor = 'unset'
        if (documentMousemoveEvent) documentMousemoveEvent.remove()
        if (documentMouseupEvent) documentMouseupEvent.remove()
        el.releaseCapture && el.releaseCapture() //当你不在需要继续获得鼠标消息就要应该调用ReleaseCapture()释放掉
      })

      el.setCapture && el.setCapture() //该函数在属于当前线程的指定窗口里设置鼠标捕获
      return false

    })
    }
})

二.使用方式

代码如下(示例):

<template>
  <div class="common-layout"  style="width:100%;">
      <div class="common-layout-left ">
      	左侧盒子
      </div>
      <div class="resize" v-el-resize></div>//自定义 v-el-resize 指令绑定在中间可拖动区域
      <div class="common-layout-right ">
      	右侧盒子
      </div>
  </div>
</template>

<style lang="scss" scoped>
.resize{
    width: 5px;
    cursor: col-resize;
 }
</style>

;