fix: 用户商品模块
This commit is contained in:
@@ -1,6 +1,9 @@
|
||||
<template>
|
||||
<div class="tags-view-container">
|
||||
<div class="tags-view-wrapper">
|
||||
<div class="tags-view-wrapper" ref="scrollWrapperRef"
|
||||
@wheel.prevent="handleWheel"
|
||||
@mouseenter="hovered = true" @mouseleave="hovered = false"
|
||||
@scroll="updateScrollbar">
|
||||
<div class="tags-view-scroll">
|
||||
<router-link
|
||||
v-for="tag in visitedViews"
|
||||
@@ -22,6 +25,9 @@
|
||||
</el-icon>
|
||||
</router-link>
|
||||
</div>
|
||||
<div class="scroll-track" :class="{ visible: hovered && hasOverflow }">
|
||||
<div class="scroll-thumb" :style="thumbStyle" @mousedown="onThumbDown"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 右键菜单 -->
|
||||
@@ -181,6 +187,65 @@ const openMenu = (e, tag) => {
|
||||
selectedTag.value = tag
|
||||
}
|
||||
|
||||
// 横向滚轮 + 自定义滚动条
|
||||
const scrollWrapperRef = ref(null)
|
||||
const hovered = ref(false)
|
||||
const hasOverflow = ref(false)
|
||||
const thumbStyle = ref({ width: '0px', left: '0px' })
|
||||
|
||||
const handleWheel = (e) => {
|
||||
if (scrollWrapperRef.value) {
|
||||
scrollWrapperRef.value.scrollLeft += e.deltaY || e.deltaX
|
||||
}
|
||||
}
|
||||
|
||||
const getTrackWidth = () => {
|
||||
const el = scrollWrapperRef.value
|
||||
if (!el) return 0
|
||||
return el.clientWidth - 24
|
||||
}
|
||||
|
||||
const updateScrollbar = () => {
|
||||
const el = scrollWrapperRef.value
|
||||
if (!el) return
|
||||
hasOverflow.value = el.scrollWidth > el.clientWidth
|
||||
if (!hasOverflow.value) return
|
||||
const tw = getTrackWidth()
|
||||
const ratio = el.clientWidth / el.scrollWidth
|
||||
const thumbW = Math.max(ratio * tw, 30)
|
||||
const maxScroll = el.scrollWidth - el.clientWidth
|
||||
const scrollRatio = maxScroll > 0 ? el.scrollLeft / maxScroll : 0
|
||||
const thumbLeft = scrollRatio * (tw - thumbW)
|
||||
thumbStyle.value = { width: thumbW + 'px', left: thumbLeft + 'px' }
|
||||
}
|
||||
|
||||
const onThumbDown = (e) => {
|
||||
e.preventDefault()
|
||||
const el = scrollWrapperRef.value
|
||||
if (!el) return
|
||||
const startX = e.clientX
|
||||
const startScroll = el.scrollLeft
|
||||
const maxScroll = el.scrollWidth - el.clientWidth
|
||||
const tw = getTrackWidth()
|
||||
const ratio = el.clientWidth / el.scrollWidth
|
||||
const thumbW = Math.max(ratio * tw, 30)
|
||||
const movable = tw - thumbW
|
||||
|
||||
const onMove = (ev) => {
|
||||
const dx = ev.clientX - startX
|
||||
const scrollDelta = movable > 0 ? (dx / movable) * maxScroll : 0
|
||||
el.scrollLeft = Math.min(Math.max(startScroll + scrollDelta, 0), maxScroll)
|
||||
}
|
||||
const onUp = () => {
|
||||
document.removeEventListener('mousemove', onMove)
|
||||
document.removeEventListener('mouseup', onUp)
|
||||
}
|
||||
document.addEventListener('mousemove', onMove)
|
||||
document.addEventListener('mouseup', onUp)
|
||||
}
|
||||
|
||||
watch(visitedViews, () => nextTick(updateScrollbar), { deep: true })
|
||||
|
||||
// 关闭右键菜单
|
||||
const closeMenu = () => {
|
||||
visible.value = false
|
||||
@@ -201,10 +266,13 @@ const handleClickOutside = () => {
|
||||
onMounted(() => {
|
||||
initTags()
|
||||
document.addEventListener('click', handleClickOutside)
|
||||
nextTick(updateScrollbar)
|
||||
window.addEventListener('resize', updateScrollbar)
|
||||
})
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
document.removeEventListener('click', handleClickOutside)
|
||||
window.removeEventListener('resize', updateScrollbar)
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -220,12 +288,13 @@ onBeforeUnmount(() => {
|
||||
.tags-view-wrapper {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 12px;
|
||||
overflow-x: auto;
|
||||
overflow-x: scroll;
|
||||
overflow-y: hidden;
|
||||
white-space: nowrap;
|
||||
position: relative;
|
||||
scrollbar-width: none;
|
||||
-ms-overflow-style: none;
|
||||
}
|
||||
|
||||
.tags-view-wrapper::-webkit-scrollbar {
|
||||
@@ -239,6 +308,37 @@ onBeforeUnmount(() => {
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.scroll-track {
|
||||
position: absolute;
|
||||
left: 12px;
|
||||
right: 12px;
|
||||
bottom: 1px;
|
||||
height: 3px;
|
||||
opacity: 0;
|
||||
transition: opacity 0.25s;
|
||||
pointer-events: none;
|
||||
z-index: 5;
|
||||
}
|
||||
|
||||
.scroll-track.visible {
|
||||
opacity: 1;
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
.scroll-thumb {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
height: 100%;
|
||||
border-radius: 3px;
|
||||
background: rgba(180,188,199,0.45);
|
||||
transition: background 0.15s;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.scroll-thumb:hover {
|
||||
background: rgba(180,188,199,0.65);
|
||||
}
|
||||
|
||||
.tag, .active-tag {
|
||||
height: 32px;
|
||||
display: inline-flex;
|
||||
|
||||
Reference in New Issue
Block a user