CustomTooltip.vue 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. <script lang="ts" setup>
  2. interface Props {
  3. visible?: boolean
  4. autoHide?: boolean
  5. autoHideDelay?: number
  6. icon?: string
  7. iconSize?: string
  8. width?: string
  9. }
  10. const props = withDefaults(defineProps<Props>(), {
  11. visible: false,
  12. autoHide: true,
  13. autoHideDelay: 10000,
  14. icon: '/static/icons/gift.png',
  15. width: '600rpx',
  16. })
  17. const emit = defineEmits<{
  18. 'update:visible': [value: boolean]
  19. 'hide': []
  20. }>()
  21. const internalVisible = ref(props.visible)
  22. let hideTimer: number | null = null
  23. // 监听 visible prop 变化
  24. watch(() => props.visible, (newVal) => {
  25. internalVisible.value = newVal
  26. if (newVal && props.autoHide) {
  27. startAutoHideTimer()
  28. }
  29. else {
  30. clearAutoHideTimer()
  31. }
  32. })
  33. // 监听内部 visible 变化
  34. watch(internalVisible, (newVal) => {
  35. emit('update:visible', newVal)
  36. if (!newVal) {
  37. emit('hide')
  38. clearAutoHideTimer()
  39. }
  40. })
  41. // 启动自动隐藏定时器
  42. function startAutoHideTimer() {
  43. clearAutoHideTimer()
  44. if (props.autoHide && props.autoHideDelay > 0) {
  45. hideTimer = setTimeout(() => {
  46. hide()
  47. }, props.autoHideDelay)
  48. }
  49. }
  50. // 清除自动隐藏定时器
  51. function clearAutoHideTimer() {
  52. if (hideTimer) {
  53. clearTimeout(hideTimer)
  54. hideTimer = null
  55. }
  56. }
  57. // 显示提示框
  58. function show() {
  59. internalVisible.value = true
  60. if (props.autoHide) {
  61. startAutoHideTimer()
  62. }
  63. }
  64. // 隐藏提示框
  65. function hide() {
  66. internalVisible.value = false
  67. }
  68. // 切换显示状态
  69. function toggle() {
  70. if (internalVisible.value) {
  71. hide()
  72. }
  73. else {
  74. show()
  75. }
  76. }
  77. // 组件卸载时清除定时器
  78. onUnmounted(() => {
  79. clearAutoHideTimer()
  80. })
  81. // 暴露方法给父组件
  82. defineExpose({
  83. show,
  84. hide,
  85. toggle,
  86. })
  87. </script>
  88. <template>
  89. <view
  90. v-if="internalVisible"
  91. class="absolute bottom-full left-1/2 mb-20rpx transform rounded-full bg-black bg-opacity-80 px-20rpx py-12rpx text-24rpx text-white -translate-x-1/2"
  92. :style="{ width }"
  93. >
  94. <view class="flex items-end justify-center">
  95. <image
  96. v-if="icon"
  97. :src="icon"
  98. class="mr-12rpx h-35rpx w-32rpx flex-shrink-0"
  99. />
  100. <view class="text-center">
  101. <text>{{ $t('productDetail.fullRefundText') }} </text>
  102. </view>
  103. </view>
  104. <!-- 倒三角箭头 -->
  105. <view
  106. class="absolute left-445rpx top-full h-0 w-0 -translate-x-1/2"
  107. style="border-left: 16rpx solid transparent; border-right: 16rpx solid transparent; border-top: 16rpx solid rgba(0, 0, 0, 0.8);"
  108. />
  109. </view>
  110. </template>