抽离上下滚动按钮组件

pull/709/head
Lemon 2025-02-22 19:56:04 +08:00
parent 212d798788
commit 009b17c91d
3 changed files with 124 additions and 112 deletions

View File

@ -4,7 +4,7 @@ NODE_ENV=development
VITE_DEV=true
# 请求路径
VITE_BASE_URL='http://localhost:48080'
VITE_BASE_URL='http://192.168.3.9:48080'
# 文件上传类型server - 后端上传, client - 前端直连上传,仅支持 S3 服务
VITE_UPLOAD_TYPE=server

View File

@ -0,0 +1,119 @@
<template>
<div class="scroll-buttons-overlay">
<div
v-show="showTopBtn"
class="scroll-btn"
@click="scrollToTop"
>
<el-icon :size="20">
<ArrowUpBold />
</el-icon>
</div>
<div
v-show="showBottomBtn"
class="scroll-btn"
@click="scrollToBottom"
>
<el-icon :size="20">
<ArrowDownBold />
</el-icon>
</div>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted, onUnmounted } from 'vue'
import { ArrowUpBold, ArrowDownBold } from '@element-plus/icons-vue'
const props = defineProps({
containerSelector: {
type: String,
required: true
},
//
scrollThreshold: {
type: Number,
default: 100
}
})
const showTopBtn = ref(false)
const showBottomBtn = ref(false)
const handleScroll = () => {
const container = document.querySelector(props.containerSelector)
if (container) {
const { scrollTop, scrollHeight, clientHeight } = container as Element
showTopBtn.value = scrollTop > props.scrollThreshold
showBottomBtn.value = scrollTop + clientHeight < scrollHeight - 10
}
}
const scrollToTop = () => {
const container = document.querySelector(props.containerSelector)
if (container) {
container.scrollTo({
top: 0,
behavior: 'smooth'
})
}
}
const scrollToBottom = () => {
const container = document.querySelector(props.containerSelector)
if (container) {
container.scrollTo({
top: (container as Element).scrollHeight,
behavior: 'smooth'
})
}
}
onMounted(() => {
const container = document.querySelector(props.containerSelector)
if (container) {
container.addEventListener('scroll', handleScroll)
}
})
onUnmounted(() => {
const container = document.querySelector(props.containerSelector)
if (container) {
container.removeEventListener('scroll', handleScroll)
}
})
</script>
<style lang="scss" scoped>
.scroll-buttons-overlay {
position: fixed;
right: calc(50% - 400px - 60px);
top: 50%;
transform: translateY(-50%);
display: flex;
flex-direction: column;
gap: 10px;
z-index: 2001;
.scroll-btn {
background-color: var(--el-color-primary);
color: white;
display: flex;
align-items: center;
justify-content: center;
width: 40px;
height: 40px;
border-radius: 50%;
box-shadow: 0 2px 12px 0 rgba(0,0,0,.1);
cursor: pointer;
transition: all 0.3s;
opacity: 0.8;
&:hover {
background-color: var(--el-color-primary);
opacity: 1;
transform: scale(1.1);
}
}
}
</style>

View File

@ -259,27 +259,8 @@
<form-create :rule="formDetailPreview.rule" :option="formDetailPreview.option" />
</div>
<!-- 将滚动按钮组移到 Dialog 组件内但在 form-detail-container -->
<div class="scroll-buttons-overlay">
<div
v-show="showTopBtn"
class="scroll-btn"
@click="scrollToTop"
>
<el-icon :size="20">
<ArrowUpBold />
</el-icon>
</div>
<div
v-show="showBottomBtn"
class="scroll-btn"
@click="scrollToBottom"
>
<el-icon :size="20">
<ArrowDownBold />
</el-icon>
</div>
</div>
<!-- 使用新组件替换原来的滚动按钮 -->
<ScrollButtons container-selector=".form-detail-container" />
</Dialog>
</template>
@ -300,6 +281,7 @@ import { useDebounceFn } from '@vueuse/core'
import { subString } from '@/utils/index'
import { ArrowUpBold, ArrowDownBold } from '@element-plus/icons-vue'
import { ElBacktop } from 'element-plus'
import ScrollButtons from '@/components/ScrollButtons/index.vue'
defineOptions({ name: 'BpmModel' })
@ -635,62 +617,6 @@ watchEffect(() => {
isExpand.value = false
}
})
//
const showTopBtn = ref(false)
//
const showBottomBtn = ref(false)
//
const handleScroll = () => {
const container = document.querySelector('.form-detail-container')
if (container) {
const { scrollTop, scrollHeight, clientHeight } = container
//
showTopBtn.value = scrollTop > 100
//
showBottomBtn.value = scrollTop + clientHeight < scrollHeight - 10
}
}
//
const scrollToTop = () => {
const container = document.querySelector('.form-detail-container')
if (container) {
container.scrollTo({
top: 0,
behavior: 'smooth'
})
}
}
//
const scrollToBottom = () => {
const container = document.querySelector('.form-detail-container')
if (container) {
container.scrollTo({
top: container.scrollHeight,
behavior: 'smooth'
})
}
}
//
onMounted(() => {
const container = document.querySelector('.form-detail-container')
if (container) {
container.addEventListener('scroll', handleScroll)
}
})
//
onUnmounted(() => {
const container = document.querySelector('.form-detail-container')
if (container) {
container.removeEventListener('scroll', handleScroll)
}
})
</script>
<style lang="scss">
@ -700,42 +626,9 @@ onUnmounted(() => {
.el-dialog__body {
position: relative;
padding: 0;
height: 70vh; //
height: 70vh;
max-height: 800px;
}
//
.scroll-buttons-overlay {
position: fixed;
right: calc(50% - 400px - 60px); // (400px)(60px)
top: 50%;
transform: translateY(-50%);
display: flex;
flex-direction: column;
gap: 10px;
z-index: 2001;
.scroll-btn {
background-color: var(--el-color-primary);
color: white;
display: flex;
align-items: center;
justify-content: center;
width: 40px;
height: 40px;
border-radius: 50%;
box-shadow: 0 2px 12px 0 rgba(0,0,0,.1);
cursor: pointer;
transition: all 0.3s;
opacity: 0.8;
&:hover {
background-color: var(--el-color-primary);
opacity: 1;
transform: scale(1.1);
}
}
}
}
.rename-dialog.el-dialog {