内凹样式的另一个方案--v-coupon 一款基于 vue 的卡券组件

v-coupon是一款基于Vue的卡券组件,解决设计师设计的有缺口卡券在CSS实现上的难题,无需依赖图片格式,提供丰富的配置选项,包括卡券尺寸、样式和裁切效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

v-coupon 一款基于 vue 的卡券组件

介绍

你是否在心里暗骂设计师设计出这种有缺口的卡券?

你是否试了多种 CSS 方案都无法完美实现?

你是否在为不得不用 jpg/png…等格式而内心挣扎?

v-coupon 就是为了解决以上痛点而诞生的。

先看看效果

在这里插入图片描述在这里插入图片描述在这里插入图片描述

如果上图你有看到白色背景,那不是 bug, 是我截图的时候页面的背景就是白色的

使用

  1. 安装
npm i v-coupon
  1. 在你的 vue 入口文件注册
import coupon from 'v-coupon'
Vue.use(coupon)
  1. 在需要展示卡券的页面使用
<v-coupon config="yourConfig">
  <div class="content">
    你要展示的内容
  </div>
</v-coupon>

当然,你也许不需要全局引入,可以直接在需要使用的页面注册 v-coupon/src/coupon.vue 组件

import vCoupon from 'v-coupon/src/coupon.vue'

// ...省略其他无关代码

components: {
    'v-coupon': vCoupon
}

详细说明

  1. <v-coupon>...</v-coupon> 之间包含的内容,是一个 slot, 这意味这 v-coupon 只提供一个裁切模版,其他内容你可以任意定制,给予你最大的发挥空间,但同时为了避免各种复杂的问题,只能有一个slot, 以下代码的第二个 div 不会被显示出来
<v-coupon config="yourConfig">
  <div class="content">
    第一个 div 的内容,会正常显示
  </div>

  <div>
    第二个 div 的内容,不会显示出来
  </div>
</v-coupon>
  1. 配置, 上例的 yourConfig 就是我们要传给 v-coupon 的配置,具体的配置项如下
{
    width: 200, // 卡券宽度
    height: 300, // 卡券高度
    borderRadius: 15, // 卡券四个角的圆角半径
    borderColor: '#33cc44', // 边框颜色
    borderWidth: 0.5, // 边框粗细
    borderOpcity: 1, // 边框透明度
    borderDash: null, // 边框虚线数组, 直线是 null, 虚线的话给一个数组,如[2,2]
    showLine: true, // 是否显示分割线
    lineColor: '#33cc44', // 分割线颜色
    lineWidth: 0.4, // 分割线粗细
    lineOpcity: 1, // 分割线透明度
    lineDash: [3, 5], // 分割线虚线数组, 同 边框虚线数组
    lineOffset: 5, // 分割线跟卡券两侧的距离, 为 0 则相连
    cutPosition: 200, // 裁切口的位置
    cutRadius: 10, // 裁切口的半径
    cutSlope: 1.5, // 裁切口的弧度
    background: '#ffffff' // 背景颜色, 优先级低于 slot 的背景
}

以上单位, 除了裁切口弧度 cutSlope 外,其他数值的单位均为 px, 暂未对其他单位做支持.

上面的配置的值, 其实就是 v-coupon 的默认值, 采用 Object.assign 的方式合并用户配置默认值, 也就是说, 你不必传所有的配置,没有传的会采用默认值

边框虚线数组 和 分割线虚线数组 有不明白的, 可以参考 MDN:SGV的stroke-dasharray属性

兼容

v-coupon 的核心内容是 SVG 的 foreignObject, 具体的兼容请参考 Can I Use

其他

v-coupon 的 github地址

有任何 bug, 需求, 意见, 建议, 吐槽, 欢迎走issue 通道, 同时也欢迎 pr.

### 实现优惠领取记录功能 在 UniApp 中实现优惠领取记录功能涉及前端页面设计以及与服务器端的数据交互。为了保存用户的领取状态并展示历史记录,通常会采用如下方式: #### 数据库表结构设计 创建一张 `coupon_records` 表用于存储每次用户成功获取到的优惠信息,字段可以包括但不限于:id (自增主键),user_id(关联用户ID), coupon_code(优惠码), created_at(时间戳)[^1]。 #### 前端逻辑处理 当用户点击按钮请求获得新的折扣劵时,在发送网络请求之前先判断本地缓存是否存在相同类型的未过期条目;如果存在则提示已拥有该类别的卡而不再重复发放;反之,则向服务端发起POST请求尝试新增一条新纪录,并更新视图显示最新的列表项。 以下是具体的代码示例来说明这一过程: ```javascript // methods.js 文件中的方法定义 export function fetchCoupons() { uni.request({ url: '/api/coupons', // 请求地址 method: 'GET', success(res) { const coupons = res.data; this.setData({coupons}); } }); } export async function claimCoupon(couponId){ try{ let response = await uni.request({ url:`/api/user/${this.userId}/claim`, data:{couponId}, method:'POST' }) if(response.statusCode===200){ console.log('Claimed successfully'); // 更新UI, 添加至已领数组中 this.coupons.push({...response.data}) }else{ throw new Error(`Failed to claim with status ${response.statusCode}`); } }catch(error){ console.error(error.message); } } ``` ```html <!-- index.vue 页面模板 --> <template> <view class="container"> <!-- 展示可选优惠 --> <block v-for="(item,index) in availableCoupons" :key="index"> <button @click="handleClick(item.id)">领取{{ item.name }}</button> </block> <!-- 显示已经领取过的优惠 --> <text>我的优惠:</text> <ul> <li v-for="(record,idx) in claimedRecords" :key="idx">{{ record.code }} - {{ formatDate(record.createdAt) }}</li> </ul> </view> </template> <script> import {fetchCoupons, claimCoupon} from './methods'; export default { data(){ return { userId: '', // 用户唯一标识符 availableCoupons:[], // 可用优惠集合 claimedRecords:[] // 已经被当前账户申领成功的实例们 }; }, onLoad(options){ this.fetchCoupons(); // 加载已有记录... uni.getStorage({ key:"claimed_coupons", success:(res)=>{ this.claimedRecords=res.data||[]; } }); }, methods:{ handleClick(id){ this.claimCoupon(id).then(()=>{ // 成功后刷新界面 this.fetchCoupons(); // 将最新的一笔加入localStorage以便下次打开应用还能看到 uni.setStorage({ key:"claimed_coupons", data:this.claimedRecords, }); }); } } }; </script> ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值