线上版本,带滑动至顶部
This commit is contained in:
parent
018cd2d099
commit
96dca18131
|
|
@ -1,9 +1,10 @@
|
|||
<template>
|
||||
<UApp>
|
||||
<NuxtLayout>
|
||||
<NuxtPage />
|
||||
</NuxtLayout>
|
||||
<NuxtLayout>
|
||||
<NuxtPage/>
|
||||
</NuxtLayout>
|
||||
<ScrollToTop/>
|
||||
</UApp>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
<script lang="ts" setup>
|
||||
</script>
|
||||
|
|
@ -1,18 +1,14 @@
|
|||
<script lang="ts" setup>
|
||||
|
||||
|
||||
const contacts = [
|
||||
{
|
||||
label: '电话',
|
||||
value: '15280659990',
|
||||
icon: 'i-heroicons-phone',
|
||||
|
||||
},
|
||||
{
|
||||
label: '邮箱',
|
||||
value: '564737095@qq.com',
|
||||
icon: 'i-heroicons-envelope',
|
||||
|
||||
},
|
||||
{
|
||||
label: '地址',
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
<UPopover mode="hover">
|
||||
<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="联系客服"
|
||||
variant="subtle"/>
|
||||
<template #content>
|
||||
|
|
|
|||
|
|
@ -1,106 +1,60 @@
|
|||
<!-- components/ScrollToTop.vue -->
|
||||
<template>
|
||||
<UButton
|
||||
v-show="isVisible"
|
||||
:aria-label="ariaLabel"
|
||||
:class="buttonClasses"
|
||||
|
||||
:icon="icon"
|
||||
|
||||
:variant="variant"
|
||||
@click="handleClick"
|
||||
@mouseenter="isHovered = true"
|
||||
@mouseleave="isHovered = false"
|
||||
>
|
||||
<!-- 插槽支持自定义内容 -->
|
||||
<slot>
|
||||
<span v-if="showText && isHovered" class="ml-2 text-xs font-medium">
|
||||
{{ text }}
|
||||
</span>
|
||||
</slot>
|
||||
</UButton>
|
||||
<!-- 悬浮置顶按钮 -->
|
||||
<Transition name="fade-slide">
|
||||
<button
|
||||
v-show="showScrollToTop"
|
||||
aria-label="回到顶部"
|
||||
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
|
||||
hover:bg-primary/95 hover:-translate-y-0.5 hover:scale-110 hover:shadow-xl
|
||||
active:scale-95 focus:ring-4 focus:ring-primary/30
|
||||
"
|
||||
title="回到顶部"
|
||||
@click="scrollToTop"
|
||||
>
|
||||
<UIcon class="w-6 h-6 text-white -rotate-45" name="i-lucide-rocket"/>
|
||||
</button>
|
||||
</Transition>
|
||||
</template>
|
||||
|
||||
<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 = () => {
|
||||
isVisible.value = window.scrollY > props.threshold
|
||||
showScrollToTop.value = window.scrollY > 300
|
||||
}
|
||||
|
||||
const handleClick = () => {
|
||||
if (props.smoothScroll) {
|
||||
window.scrollTo({top: 0, behavior: 'smooth'})
|
||||
} else {
|
||||
window.scrollTo(0, 0)
|
||||
}
|
||||
|
||||
// 触发自定义事件
|
||||
emit('click')
|
||||
// 滚动到顶部函数
|
||||
const scrollToTop = () => {
|
||||
window.scrollTo({
|
||||
top: 0,
|
||||
behavior: 'smooth'
|
||||
})
|
||||
}
|
||||
|
||||
const emit = defineEmits<{
|
||||
click: []
|
||||
}>()
|
||||
|
||||
// 组件挂载时添加滚动监听
|
||||
onMounted(() => {
|
||||
window.addEventListener('scroll', handleScroll, {passive: true})
|
||||
window.addEventListener('scroll', handleScroll)
|
||||
})
|
||||
|
||||
// 组件卸载时移除滚动监听
|
||||
onUnmounted(() => {
|
||||
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基础地址配置
|
||||
export const API_CONFIG = {
|
||||
// 开发环境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端点配置
|
||||
ENDPOINTS: {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user