线上版本,带滑动至顶部
This commit is contained in:
parent
018cd2d099
commit
96dca18131
|
|
@ -1,9 +1,10 @@
|
||||||
<template>
|
<template>
|
||||||
<UApp>
|
<UApp>
|
||||||
<NuxtLayout>
|
<NuxtLayout>
|
||||||
<NuxtPage />
|
<NuxtPage/>
|
||||||
</NuxtLayout>
|
</NuxtLayout>
|
||||||
|
<ScrollToTop/>
|
||||||
</UApp>
|
</UApp>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script lang="ts" setup>
|
||||||
</script>
|
</script>
|
||||||
|
|
@ -1,18 +1,14 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
|
||||||
|
|
||||||
const contacts = [
|
const contacts = [
|
||||||
{
|
{
|
||||||
label: '电话',
|
label: '电话',
|
||||||
value: '15280659990',
|
value: '15280659990',
|
||||||
icon: 'i-heroicons-phone',
|
icon: 'i-heroicons-phone',
|
||||||
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '邮箱',
|
label: '邮箱',
|
||||||
value: '564737095@qq.com',
|
value: '564737095@qq.com',
|
||||||
icon: 'i-heroicons-envelope',
|
icon: 'i-heroicons-envelope',
|
||||||
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '地址',
|
label: '地址',
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
<UPopover mode="hover">
|
<UPopover mode="hover">
|
||||||
<UButton
|
<UButton
|
||||||
|
|
||||||
class="bg-green-500 hover:bg-green-600 text-white px-4 py-3 rounded-l-lg shadow-lg transition-all duration-300"
|
class="bg-primary hover:bg-primary-600 text-white px-4 py-3 rounded-l-lg shadow-lg transition-all duration-300"
|
||||||
color="neutral" label="联系客服"
|
color="neutral" label="联系客服"
|
||||||
variant="subtle"/>
|
variant="subtle"/>
|
||||||
<template #content>
|
<template #content>
|
||||||
|
|
|
||||||
|
|
@ -1,106 +1,60 @@
|
||||||
<!-- components/ScrollToTop.vue -->
|
|
||||||
<template>
|
<template>
|
||||||
<UButton
|
<!-- 悬浮置顶按钮 -->
|
||||||
v-show="isVisible"
|
<Transition name="fade-slide">
|
||||||
:aria-label="ariaLabel"
|
<button
|
||||||
:class="buttonClasses"
|
v-show="showScrollToTop"
|
||||||
|
aria-label="回到顶部"
|
||||||
:icon="icon"
|
class="fixed bottom-32 right-8 z-50 rounded-full p-3 shadow-lg transition-all duration-300 focus:outline-none
|
||||||
|
bg-primary/90 backdrop-blur-md border border-white/20
|
||||||
:variant="variant"
|
hover:bg-primary/95 hover:-translate-y-0.5 hover:scale-110 hover:shadow-xl
|
||||||
@click="handleClick"
|
active:scale-95 focus:ring-4 focus:ring-primary/30
|
||||||
@mouseenter="isHovered = true"
|
"
|
||||||
@mouseleave="isHovered = false"
|
title="回到顶部"
|
||||||
|
@click="scrollToTop"
|
||||||
>
|
>
|
||||||
<!-- 插槽支持自定义内容 -->
|
<UIcon class="w-6 h-6 text-white -rotate-45" name="i-lucide-rocket"/>
|
||||||
<slot>
|
</button>
|
||||||
<span v-if="showText && isHovered" class="ml-2 text-xs font-medium">
|
</Transition>
|
||||||
{{ text }}
|
|
||||||
</span>
|
|
||||||
</slot>
|
|
||||||
</UButton>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
// 响应式状态
|
||||||
|
const showScrollToTop = ref(false)
|
||||||
|
|
||||||
interface Props {
|
// 滚动监听函数
|
||||||
threshold?: number
|
|
||||||
position?: 'br' | 'bl' | 'tr' | 'tl' // bottom-right, bottom-left, etc.
|
|
||||||
size?: 'sm' | 'md' | 'lg'
|
|
||||||
color?: 'primary' | 'green' | 'blue' | 'gray'
|
|
||||||
variant?: 'solid' | 'outline' | 'soft'
|
|
||||||
icon?: string
|
|
||||||
showText?: boolean
|
|
||||||
text?: string
|
|
||||||
ariaLabel?: string
|
|
||||||
smoothScroll?: boolean
|
|
||||||
}
|
|
||||||
|
|
||||||
const props = withDefaults(defineProps<Props>(), {
|
|
||||||
threshold: 300,
|
|
||||||
position: 'br',
|
|
||||||
size: 'lg',
|
|
||||||
color: 'green',
|
|
||||||
variant: 'solid',
|
|
||||||
icon: 'i-heroicons-arrow-up',
|
|
||||||
showText: false,
|
|
||||||
text: '回到顶部',
|
|
||||||
ariaLabel: '回到页面顶部',
|
|
||||||
smoothScroll: true
|
|
||||||
})
|
|
||||||
|
|
||||||
const isVisible = ref(false)
|
|
||||||
const isHovered = ref(false)
|
|
||||||
|
|
||||||
// 计算位置类名
|
|
||||||
const positionClasses = computed(() => {
|
|
||||||
const map = {
|
|
||||||
br: 'bottom-6 right-6',
|
|
||||||
bl: 'bottom-6 left-6',
|
|
||||||
tr: 'top-6 right-6',
|
|
||||||
tl: 'top-6 left-6'
|
|
||||||
}
|
|
||||||
return map[props.position] || map.br
|
|
||||||
})
|
|
||||||
|
|
||||||
// 计算尺寸类名
|
|
||||||
|
|
||||||
|
|
||||||
const buttonClasses = computed(() => [
|
|
||||||
'fixed z-50 rounded-full transition-all duration-300 ease-in-out',
|
|
||||||
positionClasses.value,
|
|
||||||
{
|
|
||||||
'opacity-100': isVisible.value,
|
|
||||||
'opacity-0': !isVisible.value,
|
|
||||||
'hover:scale-110': isVisible.value,
|
|
||||||
'px-4': props.showText && isHovered.value
|
|
||||||
}
|
|
||||||
])
|
|
||||||
|
|
||||||
const handleScroll = () => {
|
const handleScroll = () => {
|
||||||
isVisible.value = window.scrollY > props.threshold
|
showScrollToTop.value = window.scrollY > 300
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleClick = () => {
|
// 滚动到顶部函数
|
||||||
if (props.smoothScroll) {
|
const scrollToTop = () => {
|
||||||
window.scrollTo({top: 0, behavior: 'smooth'})
|
window.scrollTo({
|
||||||
} else {
|
top: 0,
|
||||||
window.scrollTo(0, 0)
|
behavior: 'smooth'
|
||||||
}
|
})
|
||||||
|
|
||||||
// 触发自定义事件
|
|
||||||
emit('click')
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const emit = defineEmits<{
|
// 组件挂载时添加滚动监听
|
||||||
click: []
|
|
||||||
}>()
|
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
window.addEventListener('scroll', handleScroll, {passive: true})
|
window.addEventListener('scroll', handleScroll)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// 组件卸载时移除滚动监听
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
window.removeEventListener('scroll', handleScroll)
|
window.removeEventListener('scroll', handleScroll)
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
/* 保留过渡动画 */
|
||||||
|
.fade-slide-enter-active,
|
||||||
|
.fade-slide-leave-active {
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fade-slide-enter-from,
|
||||||
|
.fade-slide-leave-to {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(10px);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -6,7 +6,8 @@
|
||||||
// API基础地址配置
|
// API基础地址配置
|
||||||
export const API_CONFIG = {
|
export const API_CONFIG = {
|
||||||
// 开发环境API地址
|
// 开发环境API地址
|
||||||
BASE_URL: 'http://192.168.1.4:4101',
|
// BASE_URL: 'http://192.168.1.4:4101',
|
||||||
|
BASE_URL: 'https://ele.ccttiot.com/prod-api',
|
||||||
|
|
||||||
// API端点配置
|
// API端点配置
|
||||||
ENDPOINTS: {
|
ENDPOINTS: {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user