vue封装可拖动式间隔条

225 阅读1分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第7天,点击查看活动详情

前言:

工作中总会遇到这种UI框架也无法满足的需求,这个时候只能自己手写了。

功能需求:

1、间隔条位于左右两个组件中间;
2、间隔条充当间隔的同时,可左右拖动(修改左右组件的宽度);
3、间隔条拖动的同时,左右被间隔的组件也要可适应宽度;

实现思路:

1、大致布局为左中右三个部分,中间组件是实现组件;
2、组件本身由一个div容器构成,为长度百分百,宽度自定义的长方形,本身颜色为透明色,鼠标触发hover事件时加灰色突出组件存在。
3、此组件最多影响本身位置,可以把本身移动的位置传递出去,作为左组件的宽度,右组件则设置宽度自适应;

实现要点:

1、进入组件监听鼠标释放(mouseup)事件;
2、组件本身需要监听div容器上的鼠标落下(mousedown)的事件;
3、鼠标落下后监听鼠标移动(mousemove)事件,并且获取移动的距离;
4、鼠标移动结束,鼠标释放=>移除鼠标移动的监听,获取最终移动值通过$emit传值给父组件;

实现效果图

22.gif

代码展示

子组件:XHandle.vue

<template>
  <div class="x-handle" @mousedown="mouseDown"></div>
</template>
 
<script>
export default {
  name: "XHandle",
  data() {
    return {
      lastX: ""
    };
  },
  mounted() {
    window.addEventListener('mouseup', this.mouseUp)
  },
  unmounted() {
    window.removeEventListener("mouseup", this.mouseUp);
  },
  methods: {
    mouseDown(event) {
      window.addEventListener("mousemove", this.mouseMove);
      this.lastX = event.screenX;
    },
    mouseMove(event) {
      this.$emit("widthChange", this.lastX - event.screenX);
      this.lastX = event.screenX;
    },
    mouseUp() {
      this.lastX = "";
      window.removeEventListener("mousemove", this.mouseMove);
    }
  }
};
</script>
<style>
.x-handle {
  padding: 5px;
  cursor: w-resize;
}
.x-handle:hover {
  background: #dbdcdf;
}
</style>

父组件使用:

<template>
  <div :style="{ width: width + 'px' }">内容1</div>
    <XHandle @widthChange="widthChange" title="可拉伸" />
  <div>内容2</div>
</template>
<script>
import XHandle from '@/components/XHandle'
export default {
  data() {
    width: 250,
  },
  methods: {
    // 监测宽度
    widthChange(movement) {
      this.width -= movement;
      if (this.width < 250) {
        this.width = 250;
      }
      if (this.width > 600) {
        this.width = 600;
      }
    },
  },
  components: {
    XHandle,
  },
}
</script>