新建组件页面
{
"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>
结果
后面就可愉快的使用这个优惠券组件啦~~