优惠券半圆镂空效果利用渐变实现,核心代码示例:
background: radial-gradient(circle at left top, transparent 6px, #ffd7d7 0) top left / 50% 100% no-repeat, radial-gradient(circle at right top, transparent 6px, #ffd7d7 0) top right / 50% 100% no-repeat;
效果图如下:
完整代码如下:
<template> <view class="content"> <view class="tabHeads"> <view class="tabLabel" @click="tabsClick(item)" v-for="(item,index) in tabsArray" :key="index"> <view :class="[isNum === item.inx?'isTabActive':'default']">{{item.name}}</view> </view> </view> <view class="headWrap"> <view class="labelDiv" :class="[isActive === item.id?'active':'']" v-for="(item,index) in labels" :key="index" @click.stop="toggle(item)"> {{item.name}} </view> </view> <scroll-view :style="'height:'+wHeight+'px'" :scroll-top="scrollTop" scroll-y="true"> <view class="couponMain"> <view class="coupon" v-for="(item,index) in coupons" :key="index"> <view class="couponTop" :class="[isNum ===1?item.type ===1?'bgColorTop1':item.type ===2?'bgColorTop2':'bgColorTop3':'bgColorTop4']"> <view class="couponTopLeft"> <view class="couponTypeDiv"> <image v-if="isNum ===1 && item.type ===1" class="imgType" src="/static/coupon/money.png" mode="aspectFit"></image> <image v-if="isNum ===1 && item.type ===2" class="imgType" src="/static/coupon/discount.png" mode="aspectFit"></image> <image v-if="isNum ===1 && item.type ===3" class="imgType" src="/static/coupon/goods.png" mode="aspectFit"></image> <image v-if="isNum !==1" class="imgType" src="/static/coupon/expired.png" mode="aspectFit"></image> <view class="tpyeNameSty">{{item.type ===1?'现金券':item.type ===2?'折扣券':'兑物券'}}</view> </view> <view class="valueSty" :class="[isNum ===1?item.type ===1?'color1':item.type ===2?'color3':'color5':'color7']"> <text v-if="item.type ===1" class="symbolMoney">¥</text> <text v-if="item.type ===1" class="moneyVal">{{item.money}}</text> <text v-if="item.type ===2" class="moneyVal">{{item.discount}}</text> <text v-if="item.type ===2" style="font-size: 14px;">折</text> <text v-if="item.type ===3" class="moneyVal">{{item.num}}</text> <text v-if="item.type ===3" style="font-size: 14px;">件</text> </view> <view v-if="item.limitCategory ===0 && item.limitStore ===0" class="useCondition" :class="[isNum ===1?item.type ===1?'borderColor1 color1':item.type ===2?'borderColor2 color3':'borderColor3 color5':'borderColor4 color7']"> 无门槛使用 </view> <view v-else class="useCondition" :class="[isNum ===1?item.type ===1?'borderColor1 color1':item.type ===2?'borderColor2 color3':'borderColor3 color5':'borderColor4 color7']"> <text>满{{item.condition}}元可</text> <text>{{item.type ===3?'兑':'用'}}</text> </view> </view> <view class="couponTopRight"> <view class="ctr-left"> <view class="couponName" :class="[isNum ===1?item.type ===1?'color1':item.type ===2?'color3':'color5':'color7']"> {{item.name}} </view> <view class="couponStore" :class="[isNum ===1?item.type ===1?'color2':item.type ===2?'color4':'color6':'color8']"> {{item.storeName}} </view> <view class="couponDate" :class="[isNum ===1?item.type ===1?'color2':item.type ===2?'color4':'color6':'color8']"> {{item.startDate}}~{{item.endDate}} </view> </view> <view class="ctr-right"> <text class="useBtn" :class="[isNum ===1?item.type ===1?'useBtnBgColor1':item.type ===2?'useBtnBgColor2':'useBtnBgColor3':'useBtnBgColor4']">{{isNum ===1?'去使用':isNum ===2?'已使用':'已过期'}}</text> </view> </view> </view> <view class="couponBottom" :class="[isNum ===1?item.type ===1?'bgColorTBottom1':item.type ===2?'bgColorTBottom2':'bgColorTBottom3':'bgColorTBottom4']"> <view class="ruleLabel"> <view class="ruleLabel-left"> <text v-if="item.overlay ===1" class="overlay" :class="[isNum ===1?item.type ===1?'color1 bgColor1':item.type ===2?'color3 bgColor2':'color5 bgColor3':'color7 bgColor4']"> {{item.overlay ===1?'可叠加':''}} </text> <text class="limit" :class="[isNum ===1?item.type ===1?'color1':item.type ===2?'color3':'color5':'color7']"> {{item.limitCategory ===1?'限品类':'不限品类'}} </text> <text class="limit" :class="[isNum ===1?item.type ===1?'color1':item.type ===2?'color3':'color5':'color7']">/</text> <text class="limit" :class="[isNum ===1?item.type ===1?'color1':item.type ===2?'color3':'color5':'color7']"> {{item.limitStore ===1?'限门店':'不限门店'}} </text> </view> <view class="ruleBtn" :class="[isNum ===1?item.type ===1?'color2':item.type ===2?'color4':'color6':'color8']" @click.stop="viewRules(item)"> <text style="margin-right: 6px;">使用规则</text> <view class="arrowIcon" :class="[item.isViewRule?isNum ===1?item.type ===1?'rotate arrowIcon1':item.type ===2?'rotate arrowIcon2':'rotate arrowIcon3':'rotate arrowIcon4':isNum ===1?item.type ===1?'backRotate arrowIcon1':item.type ===2?'backRotate arrowIcon2':'backRotate arrowIcon3':'backRotate arrowIcon4']"> </view> </view> </view> <view v-if="item.isViewRule" class="ruleDetail" :class="[isNum ===1?item.type ===1?'color2':item.type ===2?'color4':'color6':'color8']"> <view class="ruleList"> 1.使用规则描述xxxxxxxx </view> <view class="ruleList"> 1.使用规则描述xxxxxxxx </view> <view class="ruleList"> 1.使用规则描述xxxxxxxx </view> </view> </view> </view> </view> </scroll-view> </view> </template> <script> export default { data() { return { wHeight: 0, scrollTop: 0, isNum: 1, tabsArray: [{ inx: 1, name: '未使用' }, { inx: 2, name: '已使用' }, { inx: 3, name: '已过期' }], isActive: 1, labels: [{ id: 1, name: '全部' }, { id: 2, name: '现金券' }, { id: 3, name: '折扣券' }, { id: 4, name: '兑物券' }], coupons: [{ type: 1, money: 50, discount: 5, num: 1, condition: 20, name: "仅可购买指定商品", storeName: '西安碑林钟楼店', startDate: '2021-05-01', endDate: '2021-08-01', overlay: 1, limitCategory: 1, limitStore: 1, rules: '使用规则描述', isViewRule: false }, { type: 2, money: 50, discount: 5, num: 1, condition: 5, name: "仅可购买指定商品", storeName: '西安碑林钟楼店', startDate: '2021-05-01', endDate: '2021-08-01', overlay: 1, limitCategory: 0, limitStore: 0, rules: '使用规则描述', isViewRule: false }, { type: 3, money: 50, discount: 5, num: 1, condition: 20, name: "仅可购买指定商品", storeName: '西安碑林钟楼店', startDate: '2021-05-01', endDate: '2021-08-01', overlay: 1, limitCategory: 0, limitStore: 0, rules: '使用规则描述', isViewRule: false }, { type: 3, money: 50, discount: 5, num: 1, condition: 20, name: "仅可购买指定商品", storeName: '西安碑林钟楼店', startDate: '2021-05-01', endDate: '2021-08-01', overlay: 1, limitCategory: 1, limitStore: 0, rules: '使用规则描述', isViewRule: false }, { type: 3, money: 50, discount: 5, num: 1, condition: 20, name: "仅可购买指定商品", storeName: '西安碑林钟楼店', startDate: '2021-05-01', endDate: '2021-08-01', overlay: 1, limitCategory: 0, limitStore: 1, rules: '使用规则描述', isViewRule: false }, { type: 2, money: 50, discount: 5, num: 1, condition: 5, name: "仅可购买指定商品", storeName: '西安碑林钟楼店', startDate: '2021-05-01', endDate: '2021-08-01', overlay: 0, limitCategory: 0, limitStore: 0, rules: '使用规则描述', isViewRule: false }] } }, onLoad() { uni.hideTabBar() const res = uni.getSystemInfoSync() this.wHeight = res.windowHeight - 86 }, onShow() { this.isActive = 1 }, methods: { tabsClick(item) { this.isNum = item.inx }, toggle(item) { this.isActive = item.id }, viewRules(item) { if (item.isViewRule) { item.isViewRule = false } else { item.isViewRule = true } } } } </script> <style scoped> .content { padding: 0; overflow: hidden; } .tabHeads { display: flex; background-color: #fff; margin-bottom: 1px; } .tabLabel { flex: 1; display: flex; align-items: center; justify-content: center; font-size: 16px; } .default { color: #999999; padding: 10px 0; border-bottom: 1px solid #ffffff; } .isTabActive { color: #ff5555; padding: 10px 0; border-bottom: 1px solid #ff5555; } .headWrap { padding: 10px; background-color: #fff; display: flex; align-items: center; justify-content: space-between; flex-wrap: nowrap; } .labelDiv { background-color: #eeeeee; padding: 4px 20px; border-radius: 4px; color: #999999; font-size: 12px; } .active { background-color: #ff5555; color: #fff; } .couponMain { padding: 10px; display: flex; flex-direction: column; } .coupon { margin-bottom: 10px; } .couponTop { display: flex; border-top-left-radius: 4px; border-top-right-radius: 4px; } .couponTopLeft { flex: 1.2; display: flex; align-items: center; justify-content: center; flex-direction: column; position: relative; } .couponTypeDiv {} .imgType { width: 46px; height: 40px; position: absolute; top: 0; left: 0; } .tpyeNameSty { font-size: 9px; transform: rotate(-40deg); position: absolute; top: 8px; left: 2px; color: #fff; } .valueSty { margin-bottom: 10px; } .symbolMoney { font-size: 16px; } .moneyVal { font-size: 24px; } .useCondition { font-size: 10px; padding: 4px 10px; border-radius: 12px; } .couponTopRight { flex: 3; display: flex; padding-bottom: 12px; } .ctr-left { flex: 1; display: flex; flex-direction: column; } .couponName { font-size: 16px; padding: 14px 0; text-shadow: 0px 4px 6px rgba(0, 0, 0, 0.04); } .couponStore { font-size: 12px; text-shadow: 0px 4px 6px rgba(0, 0, 0, 0.04); padding-bottom: 8px; } .couponDate { font-size: 12px; text-shadow: 0px 4px 6px rgba(0, 0, 0, 0.04); } .ctr-right { display: flex; align-items: flex-end; justify-content: center; padding: 0 10px; } .useBtn { color: #fff; font-size: 12px; padding: 6px 20px; border-radius: 18px; } .couponBottom { display: flex; flex-direction: column; padding: 10px; border-bottom-left-radius: 4px; border-bottom-right-radius: 4px; } .ruleLabel { display: flex; align-items: center; } .ruleLabel-left { flex: 1; display: flex; align-items: center; } .overlay { margin-right: 10px; padding: 4px 10px; font-size: 10px; border-radius: 11px; } .limit { font-size: 12px; } .ruleBtn { display: flex; align-items: center; font-size: 12px; } .arrowIcon { position: relative; width: 6px; height: 6px; transform: rotate(135deg); } .rotate { transform: rotate(-45deg); bottom: -2px; } .backRotate { transform: rotate(135deg); top: -2px; } .ruleDetail { display: flex; flex-direction: column; } .ruleList { padding-top: 10px; font-size: 12px; } /* 颜色配置 */ .borderColor1 { border: 1px solid #5f98ff; } .borderColor2 { border: 1px solid #ff7979; } .borderColor3 { border: 1px solid #fc932c; } .borderColor4 { border: 1px solid #c3c3c3; } .arrowIcon1 { border-top: 1px solid #5f98ff; border-right: 1px solid #5f98ff; } .arrowIcon2 { border-top: 1px solid #ff7979; border-right: 1px solid #ff7979; } .arrowIcon3 { border-top: 1px solid #fc932c; border-right: 1px solid #fc932c; } .arrowIcon4 { border-top: 1px solid #c3c3c3; border-right: 1px solid #c3c3c3; } .useBtnBgColor1 { background-color: #2b6feb; } .useBtnBgColor2 { background-color: #ff5555; } .useBtnBgColor3 { background-color: #fa830e; } .useBtnBgColor4 { background-color: #bebebe; } .color1 { color: #2b6feb; } .color2 { color: #5f98ff; } .color3 { color: #ff5555; } .color4 { color: #ff7979; } .color5 { color: #fa830e; } .color6 { color: #fc932c; } .color7 { color: #bebebe; } .color8 { color: #c3c3c3; } .bgColor1 { background-color: #edf4ff; } .bgColor2 { background-color: #ffeeee; } .bgColor3 { background-color: #fff2e5; } .bgColor4 { background-color: #f3f3f3; } .bgColorTop1 { background: radial-gradient(circle at left bottom, transparent 6px, #edf4ff 0) bottom left / 50% 100% no-repeat, radial-gradient(circle at right bottom, transparent 6px, #edf4ff 0) bottom right / 50% 100% no-repeat; } .bgColorTBottom1 { background: radial-gradient(circle at left top, transparent 6px, #dae6ff 0) top left / 50% 100% no-repeat, radial-gradient(circle at right top, transparent 6px, #dae6ff 0) top right / 50% 100% no-repeat; } .bgColorTop2 { background: radial-gradient(circle at left bottom, transparent 6px, #ffeeee 0) bottom left / 50% 100% no-repeat, radial-gradient(circle at right bottom, transparent 6px, #ffeeee 0) bottom right / 50% 100% no-repeat; } .bgColorTBottom2 { background: radial-gradient(circle at left top, transparent 6px, #ffd7d7 0) top left / 50% 100% no-repeat, radial-gradient(circle at right top, transparent 6px, #ffd7d7 0) top right / 50% 100% no-repeat; } .bgColorTop3 { background: radial-gradient(circle at left bottom, transparent 6px, #fff2e5 0) bottom left / 50% 100% no-repeat, radial-gradient(circle at right bottom, transparent 6px, #fff2e5 0) bottom right / 50% 100% no-repeat; } .bgColorTBottom3 { background: radial-gradient(circle at left top, transparent 6px, #ffe0c1 0) top left / 50% 100% no-repeat, radial-gradient(circle at right top, transparent 6px, #ffe0c1 0) top right / 50% 100% no-repeat; } .bgColorTop4 { background: radial-gradient(circle at left bottom, transparent 6px, #f3f3f3 0) bottom left / 50% 100% no-repeat, radial-gradient(circle at right bottom, transparent 6px, #f3f3f3 0) bottom right / 50% 100% no-repeat; } .bgColorTBottom4 { background: radial-gradient(circle at left top, transparent 6px, #ededed 0) top left / 50% 100% no-repeat, radial-gradient(circle at right top, transparent 6px, #ededed 0) top right / 50% 100% no-repeat; } </style>