抽离上下滚动按钮组件
parent
212d798788
commit
009b17c91d
|
|
@ -4,7 +4,7 @@ NODE_ENV=development
|
||||||
VITE_DEV=true
|
VITE_DEV=true
|
||||||
|
|
||||||
# 请求路径
|
# 请求路径
|
||||||
VITE_BASE_URL='http://localhost:48080'
|
VITE_BASE_URL='http://192.168.3.9:48080'
|
||||||
|
|
||||||
# 文件上传类型:server - 后端上传, client - 前端直连上传,仅支持 S3 服务
|
# 文件上传类型:server - 后端上传, client - 前端直连上传,仅支持 S3 服务
|
||||||
VITE_UPLOAD_TYPE=server
|
VITE_UPLOAD_TYPE=server
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
@ -259,27 +259,8 @@
|
||||||
<form-create :rule="formDetailPreview.rule" :option="formDetailPreview.option" />
|
<form-create :rule="formDetailPreview.rule" :option="formDetailPreview.option" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 将滚动按钮组移到 Dialog 组件内,但在 form-detail-container 外 -->
|
<!-- 使用新组件替换原来的滚动按钮 -->
|
||||||
<div class="scroll-buttons-overlay">
|
<ScrollButtons container-selector=".form-detail-container" />
|
||||||
<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>
|
|
||||||
</Dialog>
|
</Dialog>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
@ -300,6 +281,7 @@ import { useDebounceFn } from '@vueuse/core'
|
||||||
import { subString } from '@/utils/index'
|
import { subString } from '@/utils/index'
|
||||||
import { ArrowUpBold, ArrowDownBold } from '@element-plus/icons-vue'
|
import { ArrowUpBold, ArrowDownBold } from '@element-plus/icons-vue'
|
||||||
import { ElBacktop } from 'element-plus'
|
import { ElBacktop } from 'element-plus'
|
||||||
|
import ScrollButtons from '@/components/ScrollButtons/index.vue'
|
||||||
|
|
||||||
defineOptions({ name: 'BpmModel' })
|
defineOptions({ name: 'BpmModel' })
|
||||||
|
|
||||||
|
|
@ -635,62 +617,6 @@ watchEffect(() => {
|
||||||
isExpand.value = false
|
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>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
|
|
@ -700,42 +626,9 @@ onUnmounted(() => {
|
||||||
.el-dialog__body {
|
.el-dialog__body {
|
||||||
position: relative;
|
position: relative;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
height: 70vh; // 设置固定高度
|
height: 70vh;
|
||||||
max-height: 800px;
|
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 {
|
.rename-dialog.el-dialog {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue