feat: upgrade tags view (#20)
This commit is contained in:
parent
08d820110c
commit
8df2d45932
@ -1,15 +1,81 @@
|
|||||||
|
<script lang="ts" setup>
|
||||||
|
import { ref } from "vue"
|
||||||
|
import { ElScrollbar } from "element-plus"
|
||||||
|
import { ArrowLeft, ArrowRight } from "@element-plus/icons-vue"
|
||||||
|
|
||||||
|
const scrollbarRef = ref<InstanceType<typeof ElScrollbar>>()
|
||||||
|
const scrollbarContentRef = ref<HTMLDivElement>()
|
||||||
|
|
||||||
|
/** 当前滚动条距离左边的距离 */
|
||||||
|
let currentScrollLeft = 0
|
||||||
|
/** 每次滚动距离 */
|
||||||
|
const translateDistance = 200
|
||||||
|
|
||||||
|
/** 滚动时触发 */
|
||||||
|
const scroll = ({ scrollLeft }: { scrollLeft: number }) => {
|
||||||
|
currentScrollLeft = scrollLeft
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 点击滚动 */
|
||||||
|
const scrollTo = (direction: "left" | "right") => {
|
||||||
|
let scrollLeft = 0
|
||||||
|
/** 可滚动内容的长度 */
|
||||||
|
const scrollbarContentRefWidth = scrollbarContentRef.value!.clientWidth
|
||||||
|
/** 滚动可视区宽度 */
|
||||||
|
const scrollbarRefWidth = scrollbarRef.value!.wrap$!.clientWidth
|
||||||
|
/** 最后剩余可滚动的宽度 */
|
||||||
|
const lastDistance = scrollbarContentRefWidth - scrollbarRefWidth - currentScrollLeft
|
||||||
|
// 没有横向滚动条,直接结束
|
||||||
|
if (scrollbarRefWidth > scrollbarContentRefWidth) return
|
||||||
|
if (direction === "left") {
|
||||||
|
scrollLeft = Math.max(0, currentScrollLeft - translateDistance)
|
||||||
|
} else {
|
||||||
|
scrollLeft = Math.min(currentScrollLeft + translateDistance, currentScrollLeft + lastDistance)
|
||||||
|
}
|
||||||
|
scrollbarRef.value!.setScrollLeft(scrollLeft)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<el-scrollbar :vertical="false" class="scroll-container">
|
<div class="scroll-container">
|
||||||
|
<el-icon class="arrow left" @click="scrollTo('left')">
|
||||||
|
<ArrowLeft />
|
||||||
|
</el-icon>
|
||||||
|
<el-scrollbar ref="scrollbarRef" @scroll="scroll">
|
||||||
|
<div ref="scrollbarContentRef" class="scrollbar-content">
|
||||||
<slot />
|
<slot />
|
||||||
|
</div>
|
||||||
</el-scrollbar>
|
</el-scrollbar>
|
||||||
|
<el-icon class="arrow right" @click="scrollTo('right')">
|
||||||
|
<ArrowRight />
|
||||||
|
</el-icon>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.scroll-container {
|
.scroll-container {
|
||||||
// 超出窗口长度时,显示滚动条
|
height: 100%;
|
||||||
|
user-select: none;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
.arrow {
|
||||||
|
width: 40px;
|
||||||
|
height: 100%;
|
||||||
|
cursor: pointer;
|
||||||
|
&.left {
|
||||||
|
box-shadow: 5px 0 5px -6px #ccc;
|
||||||
|
}
|
||||||
|
&.right {
|
||||||
|
box-shadow: -5px 0 5px -6px #ccc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.el-scrollbar {
|
||||||
|
flex: 1;
|
||||||
|
// 横向超出窗口长度时,显示滚动条
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
position: relative;
|
.scrollbar-content {
|
||||||
overflow: hidden;
|
display: inline-block;
|
||||||
width: 100%;
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -198,6 +198,7 @@ onMounted(() => {
|
|||||||
height: 26px;
|
height: 26px;
|
||||||
line-height: 26px;
|
line-height: 26px;
|
||||||
border: 1px solid var(--v3-tagsview-tag-border-color);
|
border: 1px solid var(--v3-tagsview-tag-border-color);
|
||||||
|
border-radius: var(--v3-tagsview-tag-border-radius);
|
||||||
color: var(--v3-tagsview-tag-text-color);
|
color: var(--v3-tagsview-tag-text-color);
|
||||||
background-color: var(--v3-tagsview-tag-bg-color);
|
background-color: var(--v3-tagsview-tag-bg-color);
|
||||||
padding: 0 8px;
|
padding: 0 8px;
|
||||||
@ -205,10 +206,10 @@ onMounted(() => {
|
|||||||
margin-left: 5px;
|
margin-left: 5px;
|
||||||
margin-top: 4px;
|
margin-top: 4px;
|
||||||
&:first-of-type {
|
&:first-of-type {
|
||||||
margin-left: 15px;
|
margin-left: 5px;
|
||||||
}
|
}
|
||||||
&:last-of-type {
|
&:last-of-type {
|
||||||
margin-right: 15px;
|
margin-right: 5px;
|
||||||
}
|
}
|
||||||
&.active {
|
&.active {
|
||||||
background-color: var(--v3-tagsview-tag-active-bg-color);
|
background-color: var(--v3-tagsview-tag-active-bg-color);
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
--v3-tagsview-tag-active-text-color: #ffffff;
|
--v3-tagsview-tag-active-text-color: #ffffff;
|
||||||
--v3-tagsview-tag-bg-color: #ffffff;
|
--v3-tagsview-tag-bg-color: #ffffff;
|
||||||
--v3-tagsview-tag-active-bg-color: #409eff;
|
--v3-tagsview-tag-active-bg-color: #409eff;
|
||||||
|
--v3-tagsview-tag-border-radius: 2px;
|
||||||
--v3-tagsview-tag-border-color: #d8dce5;
|
--v3-tagsview-tag-border-color: #d8dce5;
|
||||||
--v3-tagsview-tag-active-border-color: #409eff;
|
--v3-tagsview-tag-active-border-color: #409eff;
|
||||||
--v3-tagsview-tag-active-before-color: #ffffff;
|
--v3-tagsview-tag-active-before-color: #ffffff;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user