BannerSwiper.vue 3.33 KB
<!--
 * @Date: 2025-01-20 10:00:00
 * @LastEditors: hookehuyr hookehuyr@gmail.com
 * @LastEditTime: 2025-07-24 14:20:22
 * @FilePath: /jgdl/src/components/BannerSwiper.vue
 * @Description: 轮播图组件
-->
<template>
  <view class="px-4 pt-4" style="background: linear-gradient( 180deg, #fb923c 0%, rgba(255,203,53,0) 61%);">
    <nut-swiper :init-page="0" :pagination-visible="true" pagination-color="#ffffff" auto-play="3000"
      class="rounded-lg overflow-hidden" height="160">
      <nut-swiper-item v-for="(item, index) in bannerList" :key="index" @click="onBannerClick(item)">
        <image :src="item.image" mode="aspectFill" class="w-full h-40 object-cover" />
      </nut-swiper-item>
    </nut-swiper>
  </view>

  <!-- 图片预览组件 -->
  <nut-image-preview
    v-model:show="showImagePreview"
    :images="previewImages"
    :init-no="currentImageIndex"
  />

  <!-- 文章弹框组件 -->
  <nut-popup
    v-model:visible="showArticleModal"
    position="bottom"
    :style="{ height: '100vh' }"
    close-icon-position="bottom-right"
    :safe-area-inset-bottom="true"
  >
    <view class="article-modal">
      <!-- <view class="article-header p-4 border-b">
        <text class="text-lg font-bold">{{ currentArticle.title }}</text>
      </view> -->
      <scroll-view :scroll-y="true" :catch-move="true" class="article-content" style="height: calc(100vh - 140rpx);">
        <view class="p-4">
          <rich-text :nodes="currentArticle.content"></rich-text>
        </view>
      </scroll-view>
      <view class="article-footer p-4">
        <nut-button type="primary" block color="#fb923c" @click="closeArticleModal">
          关闭
        </nut-button>
      </view>
    </view>
  </nut-popup>
</template>

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

// 定义props
defineProps({
  bannerList: {
    type: Array,
    default: () => []
  }
})

// 定义emits
const emit = defineEmits(['bannerClick'])

// 响应式数据
const showImagePreview = ref(false)
const previewImages = ref([])
const currentImageIndex = ref(0)
const showArticleModal = ref(false)
const currentArticle = ref({
  title: '',
  content: ''
})

/**
 * 点击轮播图处理函数
 */
const onBannerClick = (item) => {
  switch (item.type) {
    case 'poster':
      // 海报图 - 显示图片预览
      previewImages.value = [item.image]
      currentImageIndex.value = 0
      showImagePreview.value = true
      break
    case 'article':
      // 文章封面图 - 显示文章弹框
      currentArticle.value = {
        title: item.title,
        content: item.content
      }
      showArticleModal.value = true
      break
    case 'vehicle':
      // 车辆封面图 - 跳转到车辆详情页
      Taro.navigateTo({
        url: `/pages/productDetail/index?id=${item.id}`
      })
      break
    default:
      console.warn('未知的轮播图类型:', item.type)
  }

  // 触发父组件事件
  emit('bannerClick', item)
}

/**
 * 关闭文章弹框
 */
const closeArticleModal = () => {
  showArticleModal.value = false
}
</script>

<style scoped>
.article-modal {
  height: 100vh;
  display: flex;
  flex-direction: column;
}

.article-content {
  overflow-y: auto;
}

.article-footer {
  position: sticky;
  bottom: 0;
  left: 0;
  right: 0;
  background: white;
  border-top: 1px solid #eee;
  padding: 16px;
  z-index: 1000;
  margin-top: auto;
}
</style>