【Vue】自定义滚动条

<!-- 滚动条开始 -->
<div class="custom-scrollbar-container">
<!-- 添加左右箭头按钮 -->
<div class="scroll-arrow left-arrow" @click="scrollBy(-100)">
<i class="iconfont"
style="transform: rotate(-90deg);display: inline-block;font-size: 24px;font-weight: 500;color:#8B8B8B ;"></i>
</div>
<div class="scroll-arrow right-arrow" @click="scrollBy(100)">
<i class="iconfont"
style="transform: rotate(90deg);display: inline-block;font-size: 24px;font-weight: 500;color:#8B8B8B"></i>
</div>
<div class="custom-scrollbar-track">
<div class="custom-scrollbar-thumb" @mousedown="startDrag" :style="{
width: `${scrollThumbWidth}px`,
left: `${scrollThumbLeft}px`
}"></div>
</div>
</div>
<!-- 滚动条结束 -->
/* 自定义滚动条 */
.custom-scrollbar-container {
/* 右对齐 */
right: 0;
position: absolute;
bottom: 64px;
width: calc(100% - 140px);
height: 10px;
background: #f8f8f8;
border-radius: 5px;
overflow: hidden;
z-index: 1;
}
.custom-scrollbar-track {
height: 100%;
position: relative;
}
.custom-scrollbar-thumb {
height: 100%;
background: #a0a0a0;
border-radius: 5px;
width: 30%;
/* 根据实际内容动态调整 */
transition: background 0.2s;
position: absolute;
cursor: pointer;
transition: left 0.2s ease;
}
.custom-scrollbar-thumb:hover {
background: #808080;
}
.scroll-arrow {
position: absolute;
top: 0;
height: 100%;
width: 15px;
margin: 0;
padding: 0;
background: #f8f8f8;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
z-index: 1;
&:hover {
background: #e8e8e8;
}
svg {
fill: #A0A0A0;
}
}
.left-arrow {
left: 0;
}
.right-arrow {
right: 0;
}
.custom-scrollbar-track {
position: absolute;
left: 15px;
right: 15px;
height: 100%;
}
// 自定义滚动条配置开始
const tableRef = ref();
const scrollPos = ref(0);
const scrollThumbWidth = ref(200);
const scrollThumbLeft = ref(0);
// 滚动条拖动逻辑
// Update the startDrag function
const startDrag = (e) => {
e.preventDefault();
if (!tableRef.value) return;
const thumb = document.querySelector('.custom-scrollbar-thumb');
const track = document.querySelector('.custom-scrollbar-track');
const table = tableRef.value.$el?.querySelector('.ant-table-body');
if (!table || !track) return;
const trackRect = track.getBoundingClientRect();
let startX = e.clientX;
let startLeft = thumb.offsetLeft;
const onMouseMove = (e) => {
const deltaX = e.clientX - startX;
let newLeft = startLeft + deltaX;
const maxLeft = trackRect.width - thumb.offsetWidth;
newLeft = Math.max(0, Math.min(newLeft, maxLeft));
const scrollWidth = table.scrollWidth - table.clientWidth;
table.scrollLeft = (newLeft / maxLeft) * scrollWidth;
// 强制更新样式
thumb.style.left = `${newLeft}px`;
};
const onMouseUp = () => {
document.removeEventListener('mousemove', onMouseMove);
document.removeEventListener('mouseup', onMouseUp);
};
document.addEventListener('mousemove', onMouseMove);
document.addEventListener('mouseup', onMouseUp);
};
// 表格滚动同步逻辑
const onTableScroll = (e) => {
const table = e.target;
const scrollWidth = table.scrollWidth - table.clientWidth;
const trackWidth = document.querySelector('.custom-scrollbar-track')?.offsetWidth || 0;
if (scrollWidth > 0 && trackWidth > 0) {
const ratio = table.scrollLeft / scrollWidth;
// 使用实时计算的滑块宽度
const currentThumbWidth = (table.clientWidth / table.scrollWidth) * trackWidth;
scrollThumbWidth.value = Math.max(20, currentThumbWidth);
// 直接计算绝对位置
scrollThumbLeft.value = ratio * (trackWidth - currentThumbWidth);
}
};
// 滚动条的箭头
const scrollBy = (delta) => {
if (!tableRef.value) return;
const table = tableRef.value.$el?.querySelector('.ant-table-body');
if (!table) return;
const newScrollLeft = table.scrollLeft + delta;
table.scrollLeft = Math.max(0, Math.min(newScrollLeft, table.scrollWidth - table.clientWidth));
onTableScroll({ target: table }); // 更新滑块位置
};
// 自定义滚动条配置结束
本代码由 Trae AI 编辑器(DeepSeek-Reasoner R1)生成

浙公网安备 33010602011771号