🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
## 如下图面板左右分割实现效果 ![](https://img.kancloud.cn/31/b6/31b6f9c5ee24f3613b1c29f90dc54c78_735x242.png) ![](https://img.kancloud.cn/ba/34/ba34181c0cc430e676a18f44e0ce010e_726x223.png) ### 公共HTML代码 ``` html   <div     ref="splitPane"     class="split-pane"     :class="direction"     :style="{ flexDirection: direction }"     @mouseleave="handleMouseleaveParent"   >     <div       v-if="$slots.left"       class="pane pane-one"       :style="directionStyle + ':' + triggerDistance"     >       <slot name="left" />     </div>     <div       v-if="$slots.left && $slots.right"       class="pane-trigger"       :style="directionStyle + ':' + barWidthPX"       @mousedown="handleMouseDown"     />     <div v-if="$slots.right" class="pane pane-right">       <slot name="right" />     </div>   </div> ``` ### 完整的逻辑代码 感兴趣的可以去查询一下[`getBoundingClientRect`](https://developer.mozilla.org/zh-CN/docs/Web/API/Element/getBoundingClientRect)方法。 ``` js export default { name: 'SplitPane', props: { direction: { type: String, default: 'row' // column }, min: { type: Number, default: 10 }, max: { type: Number, default: 60 }, defaultPercent: { // 区域1宽度 (%) type: Number, default: 15 }, triggerWidthBar: { // 滑动器宽度 (px) type: Number, default: 10 } }, data() { return { paneMovePercent: 50, // 区域1宽度 (%) triggerLeftOffset: 0 // 鼠标距滑动器左(顶)侧偏移量 } }, computed: { directionStyle() { return this.direction === 'row' ? 'width' : 'height' }, triggerDistance() { return `calc(${this.paneMovePercent}% - ${this.triggerWidthBar / 2 + 'px'})` }, barWidthPX() { return this.triggerWidthBar + 'px' } }, mounted() { this.paneMovePercent = this.defaultPercent }, methods: { // 按下滑动器 handleMouseDown(e) { document.addEventListener('mousemove', this.handleMouseMove) document.addEventListener('mouseup', this.handleMouseUp) if (this.direction === 'row') { this.triggerLeftOffset = e.pageX - e.srcElement.getBoundingClientRect().left } else { this.triggerLeftOffset = e.pageY - e.srcElement.getBoundingClientRect().top } }, // 按下滑动器后移动鼠标 handleMouseMove(e) { const clientRect = this.$refs.splitPane.getBoundingClientRect() let paneMovePercent = 0 if (this.direction === 'row') { const offset = e.pageX - clientRect.left - this.triggerLeftOffset + this.triggerWidthBar / 2 paneMovePercent = (offset / clientRect.width) * 100 } else { const offset = e.pageY - clientRect.top - this.triggerLeftOffset + this.triggerWidthBar / 2 paneMovePercent = (offset / clientRect.height) * 100 } if (paneMovePercent < this.min) { paneMovePercent = this.min } if (paneMovePercent > this.max) { paneMovePercent = this.max } this.paneMovePercent = paneMovePercent // this.$emit('update:paneMovePercent', paneMovePercent) }, handleMouseleaveParent() { this.handleMouseUp() }, // 松开滑动器 handleMouseUp() { document.removeEventListener('mousemove', this.handleMouseMove) } } } ``` ### 样式代码 ``` scss .split-pane { height: 100%; width: 100%; display: flex; &.row { .pane { height: 100%; } .pane-trigger { height: 100%; cursor: col-resize; } } &.column { .pane { width: 100%; } .pane-trigger { width: 100%; cursor: row-resize; } } .pane-trigger { background: #fff; border-right: 1px solid $comBorder; &:hover { background: $comBorder; } } .pane-right { flex: 1; } } ```