index.vue 3.33 KB
<!--
 * @Description: 分享按钮组件 - 点击后弹出分享选项
-->
<template>
  <view class="share-button-container">
    <!-- 分享按钮 -->
    <view @tap="toggleShareOptions" class="share-button">
      <text>分享</text>
    </view>

    <!-- 分享选项气泡弹窗 -->
    <view v-if="showOptions" class="share-popover">
      <view class="popover-arrow"></view>
      <view class="popover-content">
        <view class="popover-item" style="padding: 0; padding-top: 8rpx;">
          <button id="share" data-name="shareBtn" open-type="share" style="font-size: 28rpx;padding: 0; background-color: white; line-height: 2;">活动</button>
        </view>
        <view class="popover-divider"></view>
        <view @tap="handleSharePoster" class="popover-item">
          <text>海报</text>
        </view>
      </view>
    </view>

    <!-- 遮罩层 -->
    <view v-if="showOptions" class="popover-mask" @tap="hideShareOptions"></view>
  </view>
</template>

<script setup>
import { ref } from 'vue'
import Taro from '@tarojs/taro'

// 组件属性
const props = defineProps({
  // 活动数据
  activityData: {
    type: Object,
    default: () => ({})
  }
})

// 组件事件
const emit = defineEmits(['shareActivity', 'sharePoster'])

// 响应式数据
const showOptions = ref(false)

/**
 * 切换分享选项显示状态
 */
const toggleShareOptions = () => {
  showOptions.value = !showOptions.value
}

/**
 * 隐藏分享选项
 */
const hideShareOptions = () => {
  showOptions.value = false
}

/**
 * 处理活动分享
 */
const handleShareActivity = () => {
  hideShareOptions()
  emit('shareActivity', props.activityData)
}

/**
 * 处理海报分享
 */
const handleSharePoster = () => {
  hideShareOptions()
  emit('sharePoster', props.activityData)
}
</script>

<style lang="less">
.share-button-container {
  position: fixed;
  top: 40rpx;
  right: 40rpx;
  z-index: 1000;
}

.share-button {
  color: white;
  width: 80rpx;
  height: 80rpx;
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.6);
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.2);
  transition: all 0.3s ease;
  backdrop-filter: blur(10rpx);

  &:active {
    transform: scale(0.95);
    background: rgba(0, 0, 0, 0.8);
  }
}

.share-icon {
  font-size: 32rpx;
  color: white;
}

// 气泡弹窗样式
.share-popover {
  position: fixed;
  top: 140rpx;
  right: 40rpx;
  z-index: 9999;
  animation: popoverFadeIn 0.2s ease;
}

.popover-arrow {
  position: absolute;
  top: -12rpx;
  right: 30rpx;
  width: 0;
  height: 0;
  border-left: 12rpx solid transparent;
  border-right: 12rpx solid transparent;
  border-bottom: 12rpx solid white;
}

.popover-content {
  background: white;
  border-radius: 16rpx;
  box-shadow: 0 8rpx 32rpx rgba(0, 0, 0, 0.15);
  overflow: hidden;
  min-width: 160rpx;
}

.popover-item {
  padding: 24rpx 32rpx;
  font-size: 28rpx;
  color: #333;
  text-align: center;
  transition: background-color 0.2s ease;

  &:active {
    background-color: #f5f5f5;
  }
}

.popover-divider {
  height: 1rpx;
  background-color: #f0f0f0;
  margin: 0 16rpx;
}

.popover-mask {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 9998;
}

// 动画
@keyframes popoverFadeIn {
  from {
    opacity: 0;
    transform: translateY(-10rpx);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}
</style>