优惠券组件直接用 uview plus

使用

复制代码
    <!-- 优惠券弹窗 -->
    <CouponPopup 
      :show="couponPopupShow" 
      :couponList="couponList"
      @update:show="couponPopupShow = $event"
      @use="handleUseCoupon"
    />
  </view>
</template>

<script setup>

import CouponPopup from '@/pagesSubpg/hotel/components/CouponPopup/index.vue'
// 优惠券弹窗显示状态
const couponPopupShow = ref(false)

// 优惠券列表数据
const couponList = ref([
  {
    type: 'money',
    value: '10',
    condition: '150',
    name: '酒店消费券',
    startTime: '2026.04.20',
    endTime: '2026.05.20'
  },
  {
    type: 'money',
    value: '10',
    condition: '150',
    name: '酒店消费券',
    startTime: '2026.04.20',
    endTime: '2026.05.20'
  },
  {
    type: 'discount',
    value: '8.5',
    condition: '150',
    name: '酒店消费券',
    startTime: '2026.04.20',
    endTime: '2026.05.20'
  }
])

// 显示优惠券弹窗
const showCouponPopup = () => {
  couponPopupShow.value = true
}

// 使用优惠券
const handleUseCoupon = (coupon) => {
  console.log('使用优惠券:', coupon)
  uni.showToast({
    title: '已选择优惠券',
    icon: 'success'
  })
}

组件代码

复制代码
<template>
  <u-popup :show="show" mode="bottom" round="16" @close="handleClose">
    <view class="coupon-popup">
      <!-- 弹窗标题 -->
      <view class="popup-header">
        <text class="popup-title">优惠券</text>
        <view class="uicon">
          <u-icon  name="close" size="20" color="#999" @click="handleClose"></u-icon>
        </view>
      </view>

      <!-- 优惠券列表 -->
      <scroll-view scroll-y class="coupon-list">
        <view class="coupon-item" v-for="(coupon, index) in couponList" :key="index">
          <!-- 左侧金额/折扣区域 -->
          <view class="coupon-left">
            <text class="coupon-value" :class="{ 'is-discount': coupon.type === 'discount' }">
              <text class="symbol" v-if="coupon.type === 'money'">¥</text>
              {{ coupon.value }}
              <text class="unit" v-if="coupon.type === 'discount'">折</text>
            </text>
            <text class="coupon-condition">满{{ coupon.condition }}元可用</text>
          </view>

          <!-- 中间信息区域 -->
          <view class="coupon-center">
            <text class="coupon-name">{{ coupon.name }}</text>
            <text class="coupon-time">{{ coupon.startTime }} - {{ coupon.endTime }}</text>
            <text class="coupon-rule" @click="showRule(coupon)">使用规则</text>
          </view>

          <!-- 右侧操作按钮 -->
          <view class="coupon-right">
            <view class="use-btn" @click="handleUse(coupon)">去使用</view>
          </view>
        </view>
      </scroll-view>
    </view>
  </u-popup>
</template>

<script setup>
import { defineProps, defineEmits } from 'vue'

const props = defineProps({
  show: {
    type: Boolean,
    default: false
  },
  couponList: {
    type: Array,
    default: () => []
  }
})

const emit = defineEmits(['update:show', 'use'])

// 关闭弹窗
const handleClose = () => {
  emit('update:show', false)
}

// 使用优惠券
const handleUse = (coupon) => {
  emit('use', coupon)
  handleClose()
}

// 查看规则
const showRule = (coupon) => {
  uni.showToast({
    title: '查看使用规则',
    icon: 'none'
  })
}
</script>

<style lang="scss" scoped>
.coupon-popup {
  background-color: #fff;
  border-radius: 32rpx 32rpx 0 0;
  max-height: 70vh;
  display: flex;
  flex-direction: column;

  .popup-header {
    display: flex;
    align-items: center;
    justify-content:center;
    padding: 32rpx;
    position: relative;
    border-bottom: 1rpx solid #f0f0f0;

    .popup-title {
      font-size: 32rpx;
      font-weight: bold;
      color: #333;
    }

    .uicon {
      position: absolute;
      right: 30rpx;
      top: 32rpx;
    }
  }

  .coupon-list {
    flex: 1;
    padding: 24rpx 32rpx;
  }

  .coupon-item {
    display: flex;
    background: linear-gradient(135deg, #FFF5F5 0%, #FFFFFF 100%);
    border-radius: 16rpx;
    padding: 24rpx;
    margin-bottom: 20rpx;
    position: relative;
    overflow: hidden;

    // 虚线分隔效果
    &::before {
      content: '';
      position: absolute;
      left: 170rpx;
      top: 0;
      bottom: 0;
      width: 2rpx;
      background: repeating-linear-gradient(
        to bottom,
        transparent 0,
        transparent 8rpx,
        #ddd 8rpx,
        #ddd 16rpx
      );
    }

    .coupon-left {
      width: 150rpx;
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      padding-right: 20rpx;

      .coupon-value {
        font-size: 48rpx;
        font-weight: bold;
        color: #FF4D4F;
        line-height: 1;

        &.is-discount {
          font-size: 40rpx;
        }

        .symbol {
          font-size: 28rpx;
          margin-right: 4rpx;
        }

        .unit {
          font-size: 24rpx;
          margin-left: 4rpx;
        }
      }

      .coupon-condition {
        font-size: 22rpx;
        color: #FF4D4F;
        margin-top: 8rpx;
      }
    }

    .coupon-center {
      flex: 1;
      display: flex;
      flex-direction: column;
      justify-content: space-between;
      padding: 0 20rpx;

      .coupon-name {
        font-size: 28rpx;
        font-weight: bold;
        color: #333;
        margin-bottom: 8rpx;
      }

      .coupon-time {
        font-size: 24rpx;
        color: #999;
        margin-bottom: 8rpx;
      }

      .coupon-rule {
        font-size: 24rpx;
        color: #999;
        // color: #42D0E0;
      }
    }

    .coupon-right {
      display: flex;
      align-items: center;

      .use-btn {
        background: linear-gradient(135deg, #42D0E0 0%, #5EDFFF 100%);
        color: #fff;
        font-size: 26rpx;
        padding: 12rpx 32rpx;
        border-radius: 24rpx;
        text-align: center;
      }
    }
  }
}
</style>
相关推荐
高级程序源3 小时前
django校园寻物通失物招领平台32261-计算机课程设计、毕业设计
vue.js·python·mysql·小程序·django·flask·课程设计
WeiXin_DZbishe4 小时前
基于springboot宠物领养系统-计算机毕设 附源码【课程设计】94217
vue.js·spring boot·python·django·php·课程设计
架构技术专栏4 小时前
Agent 工具调用:从工具声明到执行反馈
前端·人工智能·后端
别动我齐刘海5 小时前
C++ 工程化学习
java·linux·前端·c++·学习·机器学习·机器人
志尊宝6 小时前
Vue3 零基础每日笔记(071):暗黑模式与主题切换——CSS 变量 + Element Plus 暗黑方案
前端·css·笔记·vue·html·前端开发·软件开发
WeiXin_DZbishe6 小时前
基于springboot城市公交实时运营与调度系统-计算机毕设 附源码【课程设计】66173
java·vue.js·spring boot·后端·python·php·课程设计
刘发财6 小时前
前端如何生成10000页PDF文件?
前端·javascript·开源
WeiXin_DZbishe6 小时前
基于Springboot+AI的kuall音乐广场的设计与实现-计算机毕设 附源码【课程设计】12715
vue.js·人工智能·spring boot·后端·python·php·课程设计
A接拉起0077 小时前
2026 年 JavaScript 开发者需要了解的知识
前端·javascript·后端
_馒头7 小时前
pixiJs游戏开发实践 - 跳棋小游戏
javascript·vue.js