微信小程序优惠券组件开发

发布于:2025-07-11 ⋅ 阅读:(19) ⋅ 点赞:(0)

新建组件页面

{
  "pages": [
    "components/coupon/coupon"
  ]
}

coupon.json中修改为如下代码,将页面标记为组件

{
  "component": true,
  //样式隔离,方式其他页面的样式影响
  "styleIsolation": "isolated"
}

优惠券排版

<view class="coupons-item {{(item.status===1||item.status===0)?'':'unUsed'}}">
  <!--优惠券主体-->
  <view class="top">
    <view class="left">
      <view class="strong" wx:if="{{item.type==1}}">
        <text class="small"></text>
        <text>{{item.price}}</text>
      </view>
      <view class="strong" wx:if="{{item.type==2}}">
        <text>{{item.discount}}</text>
        <text class="small"></text>
      </view>
      <view class="txt font-clamp">
        {{item.content}}
      </view>
    </view>

    <view class="right">
      <view class="txt font-clamp">{{item.name}}</view>
      <view class="time">
        <view>{{item.effective}}</view>
      </view>
      <!--未领取-->
      <view wx:if="{{item.status==0}}" bind:tap="couponClick" data-type='0' data-id="{{item.id}}" class="get-btn">领取</view>
      <!--未使用-->
      <view wx:if="{{item.status==1}}" bind:tap="couponClick" data-type='1' class="get-btn">去使用</view>
      <!--未生效-->
      <view wx:if="{{item.status==4}}" data-type='2' class="unStart-btn">未生效</view>
      <!--已使用-->
      <image wx:if="{{item.status==2}}" src="https://youhuo.alaibao.cn/Uploads/2025/07/01/250701030751574343.png" class="img" />
      <!--已过期-->
      <image wx:if="{{item.status==3}}" src="https://youhuo.alaibao.cn/Uploads/2025/07/01/250701030802499642.png" class="img" />
    </view>
  </view>
  <!--底部多余的文字说明-->
  <view class="bottom">
    <text>{{tips}}</text>
    <!--上拉收起折叠-->
    <image bind:tap="changeTips" wx:if="{{!showTipsAll}}" src="https://youhuo.alaibao.cn/Uploads/2025/07/01/250701031203394381.png" class="right" />
    <!--下拉展示更多-->
    <image  bind:tap="changeTips" wx:if="{{showTipsAll}}" src="https://youhuo.alaibao.cn/Uploads/2025/07/01/250701031159220778.png" class="right" />
  </view>
</view>

样式

.coupons-item {
  width: 670rpx;
  margin: 0 auto 20rpx;
  background: #fff2ec;
  border-radius: 18rpx;
  position: relative;
}

.coupons-item.unUsed {
  background: #ebebeb;
}

.coupons-item .top {
  display: flex;
  padding: 32rpx 24rpx 28rpx;
  height: 124rpx;
  position: relative;
}

.coupons-item .top .left {
  width: 184rpx;
  text-align: center;
  color: #ff503f;
  font-size: 24rpx;
  padding-right: 18rpx;
}

.coupons-item .top .left .strong {
  font-size: 52rpx;
  font-weight: 500;
  line-height: 52rpx;
}

.coupons-item .top .left .strong .small {
  font-size: 24rpx;
}

.coupons-item .top .left .txt {
  font-size: 22rpx;
  color: #ff503f;
}

.coupons-item .top .right {
  width: 486rpx;
  padding-top: 16rpx;
}

.coupons-item .top .right .txt {
  color: #dc2c08;
  font-size: 28rpx;
  line-height: 28rpx;
  margin-bottom: 16rpx;
  width: 330rpx;
}

.coupons-item .top .right .time {
  color: #cd897b;
  font-size: 22rpx;
  line-height: 22rpx;
  letter-spacing: -0.6rpx;
  position: relative;
  z-index: 1;
}

.coupons-item .top .right .get-btn {
  width: 124rpx;
  height: 48rpx;
  line-height: 48rpx;
  background: #ff4800;
  border-radius: 24rpx;
  color: #fff;
  position: absolute;
  right: 24rpx;
  top: 42rpx;
  font-size: 24rpx;
  text-align: center;
}

.coupons-item .top .right .get-btn.disable {
  opacity: 0.4;
}

.coupons-item .top .right .unStart-btn {
  width: 124rpx;
  height: 48rpx;
  opacity: 0.4;
  background: #FF4800;
  border-radius: 24rpx;
  line-height: 48rpx;
  color: #fff;
  position: absolute;
  right: 24rpx;
  top: 42rpx;
  font-size: 24rpx;
  text-align: center;
}

.coupons-item .top .right .img {
  width: 143rpx;
  height: 143rpx;
  position: absolute;
  top: 0;
  right: 28rpx;
}

.coupons-item.unUsed .top .left {
  color: #666666;
}

.coupons-item.unUsed .top .left .txt {
  color: #666666;
}

.coupons-item.unUsed .top .right .txt {
  color: #666666;
}

.coupons-item.unUsed .top .right .time {
  color: #9b9b9b;
}

.coupons-item .bottom {
  width: 670rpx;
  min-height: 56rpx;
  line-height: 28rpx;
  background: #f8f8f7;
  font-size: 20rpx;
  color: #9b9b9b;
  padding: 12rpx 62rpx 16rpx 24rpx;
  border-radius: 0 0 18rpx 18rpx;
  border-top: 2rpx dotted #f9e5de;
  position: relative;
  box-sizing: border-box;
}

.coupons-item .bottom::before {
  content: '';
  position: absolute;
  top: -10rpx;
  left: -10rpx;
  width: 20rpx;
  height: 20rpx;
  background: #fff;
  border-radius: 50%;
  z-index: 1;
}

.coupons-item .bottom::after {
  content: '';
  position: absolute;
  top: -10rpx;
  left: auto;
  right: -10rpx;
  width: 20rpx;
  height: 20rpx;
  background: #fff;
  border-radius: 50%;
  z-index: 1;
}

.coupons-item .bottom .right {
  position: absolute;
  top: 24rpx;
  right: 24rpx;
  width: 22rpx;
  height: 12rpx;
}

优惠券后台逻辑

Component({
  properties: {
    item: {
      type: Object,
      value: {}
      /*
      //传递过来的数据
      {
        id:1,
        type: 1, // 1:满减券 2:折扣券 
        price: 10, // 10元可用 
        discount: 5, // 5折可用 
        content: '满10减9', // 满减说明 
        name: '通用优惠券名称',
        effective: '领券后当天生效,有效期 30 天',
        status: 1, //0未领取 1,未使用 ,2、已使用 3、已过期 4、未生效 
        initTxt: '优惠券的一些说明,这里可以很长也可以很短优惠券的一些说明,这里可以很长也可以很短'
      }
      */
    }
  },
  lifetimes: {
    attached: function () {
      this.setTips();
    },
  },
  methods: {
    /**
     * 按钮被点击通知父组件
     * @param {*} e 
     */
    couponClick(e) {
      let id = e.currentTarget.dataset.id;
      let type = e.currentTarget.dataset.id;
      this.triggerEvent('btnClick', {
        id,
        type
      });
    },
    /**
     * 设置文字显示内容
     */
    setTips() {
      let initTxt = this.data.item.initTxt;
      if (this.data.showTipsAll) {
        this.setData({
          tips: initTxt
        })
      } else {
        let tips = initTxt.length > 28 ? initTxt.substring(0, 28) + '...' : initTxt;
        this.setData({
          tips: tips
        })
      }
    },
    /**
     * 改变文字的显示与隐藏
     */
    changeTips() {
      const isShow = !this.data.showTipsAll;
      this.setData({
        showTipsAll: isShow
      }, () => {
        this.setTips();
      })
    }
  },
  data: {
    //优惠券多余的文字
    tips: "",
    //是否全部显示
    showTipsAll: false,
  }
})

使用优惠券组件

使用的页面中声明组件

{
  "usingComponents": {
    "coupon":"/components/coupon/coupon"
  }
}

模拟数据以及监听组件按钮的点击事件

Page({
  /**
   * 页面的初始数据
   */
  data: {
    couponList: [{
        id: 1,
        type: 1, // 1:满减券 2:折扣券 
        price: 35, // 35元可用 
        content: '满35减5', // 满减说明 
        name: '通用优惠券名称',
        effective: '领券后生效,有效期 1 天',
        status: 0, //0未领取 1,未使用 ,2、已使用 3、已过期 4、未生效 
        initTxt: '优惠券的一些说明,这里可以很长也可以很短优惠券的一些说明,这里可以很长也可以很短'
      },
      {
        id: 2,
        type: 2, // 1:满减券 2:折扣券 
        discount: 8,
        content: '满100元可用', // 满减说明 
        name: '打折优惠券名称',
        effective: '领券后生效,有效期 1 天',
        status: 1, //0未领取 1,未使用 ,2、已使用 3、已过期 4、未生效 
        initTxt: '优惠券的一些说明,这里可以很长也可以很短优惠券的一些说明,这里可以很长也可以很短'
      },
      {
        id: 3,
        type: 1, // 1:满减券 2:折扣券 
        price: 35, // 35元可用 
        content: '满35减5', // 满减说明 
        name: '通用优惠券名称',
        effective: '领券后生效,有效期 1 天',
        status: 2, //0未领取 1,未使用 ,2、已使用 3、已过期 4、未生效 
        initTxt: '优惠券的一些说明,这里可以很长也可以很短优惠券的一些说明,这里可以很长也可以很短'
      },
      {
        id: 4,
        type: 1, // 1:满减券 2:折扣券 
        price: 35, // 35元可用 
        content: '满35减5', // 满减说明 
        name: '通用优惠券名称',
        effective: '领券后生效,有效期 1 天',
        status: 3, //0未领取 1,未使用 ,2、已使用 3、已过期 4、未生效 
        initTxt: '优惠券的一些说明,这里可以很长也可以很短优惠券的一些说明,这里可以很长也可以很短'
      },
      {
        id: 5,
        type: 1, // 1:满减券 2:折扣券 
        price: 35, // 35元可用 
        content: '满35减5', // 满减说明 
        name: '通用优惠券名称',
        effective: '领券后生效,有效期 1 天',
        status: 4, //0未领取 1,未使用 ,2、已使用 3、已过期 4、未生效 
        initTxt: '优惠券的一些说明,这里可以很长也可以很短优惠券的一些说明,这里可以很长也可以很短'
      },
    ]
  },
  myBtnClick(e) {
    //e.detail中获取想要的数据然后进行后续的处理
    console.log(e);
  }
})

前台渲染数据

<view>
  <block wx:for="{{couponList}}" wx:key="index">
    <coupon item="{{item}}" bind:btnClick="myBtnClick"></coupon>
  </block>
</view>

结果

在这里插入图片描述

后面就可愉快的使用这个优惠券组件啦~~


网站公告

今日签到

点亮在社区的每一天
去签到