效果图如下:
封装组件
<template><div ref="container" class="container"><div class="left-content" :style="leftStyle">/**定义左侧插槽**/<slot name="left"></slot></div><div ref="spliter" style="height: 100%; width: 10px" class="spliter-bar" /><div class="right-content" :style="rightStyle">/**定义右侧插槽**/<slot name="right"></slot></div></div>
</template><script setup lang="ts">
import { ref, onMounted, onUnmounted } from 'vue';const container:any = ref(null);
const spliter:any = ref(null);
const leftStyle:any= ref({});
const rightStyle:any = ref({});
const ratio:any = ref(0.6); //初始化左右的宽度const emits = defineEmits(['changeIframe'])function updatePaneStyles(newRatio:any) {leftStyle.value = { width: `calc(${newRatio * 100}% - 5px)` };rightStyle.value = { width: `calc(${(1 - newRatio) * 100}% - 5px)` };
}function handleResize(e:any) {const containerWidth = container.value.clientWidth;const rect = container.value.getBoundingClientRect();const initX = rect.left;function onMouseMove(e:any) {emits('changeIframe','none')e.preventDefault();// 限制鼠标移动事件的范围为container容器四至范围内if (e.clientX < rect.left || e.clientX > rect.right || e.clientY < rect.top || e.clientY > rect.bottom) {onMouseUp();}const moveScale = (e.clientX - initX) / containerWidth;const newRatio = moveScale;if (newRatio > 0.05 && newRatio < 0.95) {ratio.value = newRatio;updatePaneStyles(newRatio);}}function onMouseUp() {emits('changeIframe','auto')document.removeEventListener('mousemove', onMouseMove);document.removeEventListener('mouseup', onMouseUp);}document.addEventListener('mousemove', onMouseMove);document.addEventListener('mouseup', onMouseUp);
}function onDblClick(e:any) {ratio.value = 0.6;updatePaneStyles(ratio.value);
}onMounted(() => {updatePaneStyles(ratio.value);if (spliter.value) {spliter.value.addEventListener('mousedown', handleResize, false);spliter.value.addEventListener('dblclick', onDblClick, false);}
})
onUnmounted(() => {if (spliter.value) {spliter.value.removeEventListener('mousedown', handleResize);spliter.value.removeEventListener('dblclick', onDblClick);}
})
</script><style scoped>
.container {width: 100%;height: 100%;display: flex;flex-direction: row;
}.left-content {height: 100%;z-index: 1;overflow: scroll;display: flex;flex-direction: column;
}.right-content {height: 100%;z-index: 1;
}.spliter-bar {cursor: col-resize;position: relative;z-index: 2;-webkit-user-select: none;-moz-user-select: none;-ms-user-select: none;user-select: none;&:before,&:after {content: '';position: absolute;top: 50%;left: 50%;background-color: rgba(0, 0, 0, 0.15);width: 1.5px;height: 30px;}&:before {margin-left: -2px;}&:after {margin-left: 1px;}&:hover:before,&:hover:after {width: 1.5px;background-color: rgba(0, 0, 0, 0.35);}
}
</style>
页面使用
注意⚠️:
如果内容区域里面有iframe标签引入的页面,此时左右拖动会出看卡顿显现,此时可能通过动态修改pointerEvents的值来解决卡顿问题。当鼠标按下拖动的时候,将pointerEvents设置为’none’,鼠标弹起的时候设置为‘auto’,默认值是‘atuo’(如果左右是正常布局没有iframe加载的内容则可以忽略上面的触发父组件的事件)
组件封装参考http://t.csdnimg.cn/u7RVl