Skip to content
本页目录

介绍

vue 实现2个盒子 自由拖拽,改变宽度。

源码

html
<template>
  <div ref="dragBox" style="display: flex; width: 100%; height: 100%;">
    <div ref="dragBoxLeft" style="min-width: 200px;position: relative;" :style="`width:${leftWidth}`">
      <div style="width: 100%; height: 100%;">
        <slot name="BoxLeft">默认信息</slot>
      </div>
      <!-- 拖拽条 -->
      <div class="resize" ref="resizeButton" />
    </div>
    <div ref="dragBoxRight" style="min-width: 200px; position: relative;">
      <div style="width: 100%; height: 100%;">
        <slot name="BoxRight">默认信息</slot>
      </div>
      <!-- 拖拽条 -->
      <!--      <div v-if="resizeShow" class="resize" />-->
    </div>
  </div>
</template>
vue
export default {
  name: 'LeftRightMove',
  mixins: [],
  filters: {},
  components: {},
  props: {
    leftWidth: {
      type: String,
      required: false,
      default: '60%'
    }
  },
  data() {
    return {}
  },
  computed: {},
  watch: {},
  created() {
  },
  mounted() {
    this.setDragItemFlex()
  },
  destroyed() {
  },
  methods: {
    //  没有定义宽度,则flex=1
    setDragItemFlex() {
      // const dragBoxLeft = this.$refs['dragBoxLeft']
      const dragBoxRight = this.$refs['dragBoxRight']
      if (!dragBoxRight.style.width) {
        dragBoxRight.style.flex = 1
      }
      const resizeButton = this.$refs['resizeButton']
      resizeButton.addEventListener('mousedown', this.onMouseDown)
    },
    onMouseDown(e) {
      this.resizeBox = e.target
      this.currentBox = e.target.parentNode// 当前盒子
      this.rightBox = this.getNextElement(this.currentBox)// 当前盒子的下个兄弟节点
      if (!this.rightBox) return
      this.curLen = this.currentBox.clientWidth
      this.otherBoxWidth = this.$refs['dragBox'].clientWidth - this.currentBox.clientWidth - this.rightBox.clientWidth // 其他盒子的宽度
      // 颜色改变提醒
      e.target.style.background = '#409EFF'
      this.startX = e.clientX
      document.addEventListener('mousemove', this.onMousemove)
      document.addEventListener('mouseup', this.onMouseup)
    },

    // 获取下一个兄弟元素的兼容函数
    getNextElement(element) {
      if (element.nextElementSibling) {
        return element.nextElementSibling
      } else {
        let next = element.nextSibling// 下一个兄弟节点
        while (next && next.nodeType !== 1) { // 有 并且 不是我想要的
          next = next.nextSibling
        }
        return next
      }
    },
    onMousemove(e) {
      const endX = e.clientX
      const moveLen = endX - this.startX // (endx-startx)= 移动的距离
      const CurBoxLen = this.curLen + moveLen // resizeButton.left+移动的距离=左边区域最后的宽度
      const rightBoxLen = this.$refs['dragBox'].clientWidth - CurBoxLen - this.otherBoxWidth // 右侧宽度=总宽度-左侧宽度-其它盒子宽度
      // 当最小宽度时,无法继续拖动
      if (CurBoxLen <= 200 || rightBoxLen <= 200) return
      this.currentBox.style.width = CurBoxLen + 'px'// 当前盒子的宽度
      e.target.style.left = CurBoxLen // 设置左侧区域的宽度
      this.rightBox.style.width = rightBoxLen + 'px'
    },
    onMouseup() {
      // 颜色恢复
      this.resizeBox.style.background = '#F2F6FC'
      document.removeEventListener('mousedown', this.onMouseDown)
      document.removeEventListener('mousemove', this.onMousemove)
    }
  }
}
scss
.resize {
  position: absolute;
  top: 0;
  right: 0;
  width: 4px;
  height: 100%;
  cursor: col-resize;
  background-color: #F2F6FC;
}