97 lines
2.0 KiB
Vue
97 lines
2.0 KiB
Vue
<!-- components/ContactFloatingButton.vue -->
|
|
<template>
|
|
<div class="fixed right-6 top-1/2 transform -translate-y-1/2 z-50 flex items-center">
|
|
<!-- 二维码面板 -->
|
|
<Transition name="fade-slide">
|
|
<div v-if="showQR" class="w-64 overflow-hidden transition-all duration-300 ease-out;">
|
|
<img
|
|
:alt="qrAltText"
|
|
:src="qrImage"
|
|
class="w-full h-auto border-4 border-white rounded-lg shadow-xl"
|
|
>
|
|
</div>
|
|
</Transition>
|
|
|
|
<!-- 客服按钮 -->
|
|
<button
|
|
:class="{ 'ml-2': showQR }"
|
|
class="bg-green-500 hover:bg-green-600 text-white px-4 py-3 rounded-l-lg shadow-lg transition-all duration-300"
|
|
@click="onButtonClick"
|
|
@mouseenter="showQR = true"
|
|
@mouseleave="onMouseLeave"
|
|
>
|
|
<span class="button-text">{{ buttonText }}</span>
|
|
</button>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup>
|
|
import {ref} from 'vue'
|
|
|
|
const props = defineProps({
|
|
qrImage: {
|
|
type: String,
|
|
default: '/img/img.png'
|
|
},
|
|
qrAltText: {
|
|
type: String,
|
|
default: '客服二维码'
|
|
},
|
|
buttonText: {
|
|
type: String,
|
|
default: '联系客服'
|
|
},
|
|
hoverDelay: {
|
|
type: Number,
|
|
default: 300 // 延迟隐藏时间(ms)
|
|
}
|
|
})
|
|
|
|
const emit = defineEmits(['click'])
|
|
|
|
const showQR = ref(false)
|
|
let hideTimer = null
|
|
|
|
const onMouseLeave = () => {
|
|
hideTimer = setTimeout(() => {
|
|
showQR.value = false
|
|
}, props.hoverDelay)
|
|
}
|
|
|
|
const cancelHide = () => {
|
|
if (hideTimer) {
|
|
clearTimeout(hideTimer)
|
|
hideTimer = null
|
|
}
|
|
}
|
|
|
|
const onButtonClick = () => {
|
|
emit('click')
|
|
// 点击后保持二维码显示
|
|
cancelHide()
|
|
showQR.value = true
|
|
}
|
|
</script>
|
|
|
|
<style scoped>
|
|
/* 按钮样式 */
|
|
|
|
|
|
.writing-mode-vertical {
|
|
writing-mode: vertical-rl;
|
|
text-orientation: mixed;
|
|
}
|
|
|
|
|
|
/* 动画效果 */
|
|
.fade-slide-enter-active,
|
|
.fade-slide-leave-active {
|
|
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
|
}
|
|
|
|
.fade-slide-enter-from,
|
|
.fade-slide-leave-to {
|
|
opacity: 0;
|
|
transform: translateX(10px);
|
|
}
|
|
</style> |