mirror of
https://github.com/un-pany/v3-admin-vite.git
synced 2025-04-22 03:49:19 +08:00
feat: upgrade tags view
This commit is contained in:
parent
9f82e4626f
commit
395617f2d3
@ -1,15 +1,86 @@
|
||||
<script lang="ts" setup>
|
||||
import { ref } from "vue"
|
||||
import { ElScrollbar } from "element-plus"
|
||||
import { ArrowLeftBold, ArrowRightBold } from "@element-plus/icons-vue"
|
||||
const scrollContainerRef = ref<HTMLDivElement>()
|
||||
const scrollbarBoxRef = ref<HTMLDivElement>()
|
||||
const scrollbarRef = ref<InstanceType<typeof ElScrollbar>>()
|
||||
|
||||
// current scrolled distance
|
||||
let currentScrollLeft = 0
|
||||
// the distance of each manual trigger scroll
|
||||
const translatePerDistance = 200
|
||||
const toleranceDistance = 40
|
||||
|
||||
// scroll trigger
|
||||
const scrollChange = ({ scrollLeft = 0 }) => {
|
||||
currentScrollLeft = scrollLeft
|
||||
}
|
||||
|
||||
// click to scroll
|
||||
const scrollTo = (type: string) => {
|
||||
// container width
|
||||
const scrollContainerWidth = scrollContainerRef.value!.clientWidth
|
||||
// content width
|
||||
const scrollbarBoxWidth = scrollbarBoxRef.value!.clientWidth
|
||||
// If no scroll bar appears, return directly
|
||||
if (scrollContainerWidth > scrollbarBoxWidth) return
|
||||
let translateDistance = 0
|
||||
if (type === "prev") {
|
||||
translateDistance =
|
||||
currentScrollLeft > translatePerDistance + toleranceDistance ? currentScrollLeft - translatePerDistance : 0
|
||||
} else if (type === "next") {
|
||||
// remaining unscrolled width on the right
|
||||
const lastDistance = scrollbarBoxWidth - currentScrollLeft - scrollContainerWidth
|
||||
translateDistance =
|
||||
lastDistance > translatePerDistance + toleranceDistance
|
||||
? currentScrollLeft + translatePerDistance
|
||||
: currentScrollLeft + lastDistance
|
||||
}
|
||||
scrollbarRef.value!.setScrollLeft(translateDistance)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<el-scrollbar :vertical="false" class="scroll-container">
|
||||
<slot />
|
||||
</el-scrollbar>
|
||||
<div ref="scrollContainerRef" class="scroll-container">
|
||||
<el-button class="scroll-indicator prev" :icon="ArrowLeftBold" @click="scrollTo('prev')" />
|
||||
<el-scrollbar ref="scrollbarRef" :vertical="false" class="scroll-bar" @scroll="scrollChange">
|
||||
<div ref="scrollbarBoxRef" class="scroll-bar_box">
|
||||
<slot />
|
||||
</div>
|
||||
</el-scrollbar>
|
||||
<el-button class="scroll-indicator next" :icon="ArrowRightBold" @click="scrollTo('next')" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.scroll-container {
|
||||
// 超出窗口长度时,显示滚动条
|
||||
white-space: nowrap;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
width: 100%;
|
||||
.scroll-indicator {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
z-index: 1;
|
||||
padding: 2px;
|
||||
&.prev {
|
||||
left: 0;
|
||||
}
|
||||
&.next {
|
||||
right: 0;
|
||||
}
|
||||
}
|
||||
.scroll-bar {
|
||||
// 超出窗口长度时,显示滚动条
|
||||
white-space: nowrap;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
width: 100%;
|
||||
:deep(.el-scrollbar__wrap) {
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
.scroll-bar_box {
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -205,10 +205,10 @@ onMounted(() => {
|
||||
margin-left: 5px;
|
||||
margin-top: 4px;
|
||||
&:first-of-type {
|
||||
margin-left: 15px;
|
||||
margin-left: 24px;
|
||||
}
|
||||
&:last-of-type {
|
||||
margin-right: 15px;
|
||||
margin-right: 24px;
|
||||
}
|
||||
&.active {
|
||||
background-color: var(--v3-tagsview-tag-active-bg-color);
|
||||
|
Loading…
x
Reference in New Issue
Block a user