<template>
<a-layout>
<a-layout-sider
v-model:collapsed="collapsed"
:width="sidebarWidth"
:style="{ overflow: 'visible' }"
@mousedown.stop="startResize($event)"
>
<div class="sider-resize" @mousedown.stop="startResize($event)"></div>
<!-- 侧边栏内容 -->
</a-layout-sider>
<a-layout>
<!-- 主体内容 -->
</a-layout>
</a-layout>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
export default defineComponent({
data() {
return {
collapsed: false,
sidebarWidth: 200,
resizing: false,
startX: 0,
startWidth: 200,
moveHandler: null as null | ((event: MouseEvent) => void),
};
},
methods: {
startResize(event: MouseEvent) {
this.resizing = true;
this.startX = event.clientX;
this.startWidth = this.sidebarWidth;
this.moveHandler = this.resize.bind(this);
document.addEventListener('mousemove', this.moveHandler);
document.addEventListener('mouseup', this.stopResize);
},
resize(event: MouseEvent) {
if (this.resizing) {
const deltaX = event.clientX - this.startX;
this.sidebarWidth = Math.max(this.startWidth + deltaX, 100);
}
},
stopResize() {
this.resizing = false;
document.removeEventListener('mousemove', this.moveHandler!);
document.removeEventListener('mouseup', this.stopResize);
this.moveHandler = null;
window.getSelection()?.removeAllRanges();
},
},
});
</script>
<style>
.sider-resize {
position: absolute;
top: 0;
right: -5px;
width: 10px;
height: 100%;
cursor: col-resize;
}
</style>
- 在
data
中添加了moveHandler
属性,用于存储resize
方法的绑定版本。 - 在
startResize
方法中,使用bind
创建了resize
方法的绑定版本,并将其赋值给moveHandler
。 - 在
stopResize
方法中,使用removeEventListener
移除了moveHandler
指向的事件监听器,而不是直接移除resize
方法。 - 同时,在
stopResize
方法中,我们调用了window.getSelection()?.removeAllRanges()
来清除浏览器的选区,这样可以防止某些浏览器在拖动过程中出现文本选择的情况。