携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第7天,点击查看活动详情
前言:
工作中总会遇到这种UI框架也无法满足的需求,这个时候只能自己手写了。
功能需求:
1、间隔条位于左右两个组件中间;
2、间隔条充当间隔的同时,可左右拖动(修改左右组件的宽度);
3、间隔条拖动的同时,左右被间隔的组件也要可适应宽度;
实现思路:
1、大致布局为左中右三个部分,中间组件是实现组件;
2、组件本身由一个div容器构成,为长度百分百,宽度自定义的长方形,本身颜色为透明色,鼠标触发hover事件时加灰色突出组件存在。
3、此组件最多影响本身位置,可以把本身移动的位置传递出去,作为左组件的宽度,右组件则设置宽度自适应;
实现要点:
1、进入组件监听鼠标释放(
mouseup)事件;
2、组件本身需要监听div容器上的鼠标落下(mousedown)的事件;
3、鼠标落下后监听鼠标移动(mousemove)事件,并且获取移动的距离;
4、鼠标移动结束,鼠标释放=>移除鼠标移动的监听,获取最终移动值通过$emit传值给父组件;
实现效果图
代码展示
子组件: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>