@yeez-tech/redeem-coupon-ui
v0.1.0
Published
Vue 3 兑换券流程:弹窗校验、海报卡片栈、光效按钮;业务通过 props 注入回调。
Readme
redeem-coupon-ui
Vue 3 兑换券 UI:光效入口 → 兑换码弹窗 →(可选)海报图 → 卡片栈 → 下载。业务通过 props 传入校验、海报与点击等逻辑。
Requirements
需与下列 peer 一并安装(版本以 package.json 的 peerDependencies 为准):
vue ^3.2(支持3.2/3.3/3.4/3.5)@arco-design/web-vue(组件内使用 Modal / Button / Input)motion-v(卡片栈)
Install
npm install redeem-coupon-uiSetup
- 在应用入口注册 Arco Design Vue 并引入样式:
import { createApp } from 'vue'
import ArcoVue from '@arco-design/web-vue'
import '@arco-design/web-vue/dist/arco.css'
import App from './App.vue'
const app = createApp(App)
app.use(ArcoVue)
app.mount('#app')- 引入本包样式(必须):
import 'redeem-coupon-ui/style.css'- 默认海报渲染逻辑已内置在组件包中,接入方无需额外拷贝
poster-canvas.js或改index.html。 若不使用默认海报,可传入自定义enrichItemsWithPosters覆盖默认实现。
Publish (recommended)
建议通过 npm 正式发包给业务项目安装,不要长期依赖 npm link。
发布前检查:
package.json中vue保持peerDependencies(不要放入dependencies)。- 库构建配置将
vue与@vue/runtime-*设为external,避免消费方出现双 Vue runtime。 - 执行
npm pack检查包内容,仅包含dist与typings。
发布流程:
npm version patch
npm publish消费方安装:
npm install redeem-coupon-uiQuick start
<script setup lang="ts">
import { RedeemCoupon } from 'redeem-coupon-ui'
import type { RedeemValidateResult } from 'redeem-coupon-ui'
async function validateRedeemCode(code: string): Promise<RedeemValidateResult> {
const res = await fetch('/api/redeem', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ code })
})
return res.json()
}
</script>
<template>
<RedeemCoupon :validate-redeem-code="validateRedeemCode" />
</template><script setup> 中 import 的组件可直接在模板中使用,无需再注册。
RedeemCoupon Props
| Prop | 类型 | 必填 | 说明 |
|------|------|------|------|
| validateRedeemCode | (code: string) => Promise<RedeemValidateResult> | 是 | 校验兑换码,返回成功列表或错误信息 |
| enrichItemsWithPosters | EnrichItemsWithPosters | 否 | 将 items 转为带展示图(如海报);不传则使用库内固定默认逻辑 |
| logoUrl | string | 否 | 内置海报时传给 Canvas 的 Logo(URL 或 data URL) |
| onCardClick | (payload: RedeemCardClickPayload) => void | 否 | 点击卡片;不传则默认在新窗口打开 href 或图片地址 |
| onDownload | (items: RedeemItem[]) => void \| Promise<void> | 否 | 点击「下载数据」 |
| onRedeemSuccess | (items: RedeemItem[]) => void | 否 | 校验与海报处理完成后 |
| posterCardDimensions | { width: number; height: number } | 否 | 卡片栈中单卡尺寸 |
| pageTitle / modalTitle / inputPlaceholder | string | 否 | 文案 |
| redeemButtonText / downloadButtonText / cancelButtonText / confirmButtonText | string | 否 | 按钮文案 |
| couponIconSrc | string | 否 | 入口按钮旁图标 URL |
| showDownloadButton | boolean | 否 | 是否显示下载按钮,默认 true |
| borderGlowColors | string[] | 否 | 光效边框配色 |
| useDefaultTrigger | boolean | 否 | 是否使用库内置光效入口按钮,默认 false(推荐由接入方自定义触发器) |
插槽
| 插槽 | 作用域参数 | 说明 |
|------|------------|------|
| trigger | { openModal, submitting } | 自定义入口触发器(推荐);调用 openModal() 打开兑换弹窗 |
| success-message | { count: number } | 兑换成功后的顶部说明文案 |
更多示例
自定义海报(不依赖 PosterRenderer)
<script setup lang="ts">
import { RedeemCoupon } from 'redeem-coupon-ui'
import type { RedeemValidateResult, EnrichItemsWithPosters } from 'redeem-coupon-ui'
async function validateRedeemCode(code: string): Promise<RedeemValidateResult> {
/* ... */
return { ok: true, items: [] }
}
const enrichItemsWithPosters: EnrichItemsWithPosters = async (items, _ctx) => {
return items.map((i) => ({ ...i, imageUrl: 'https://example.com/poster.png' }))
}
</script>
<template>
<RedeemCoupon
:validate-redeem-code="validateRedeemCode"
:enrich-items-with-posters="enrichItemsWithPosters"
/>
</template>内置海报 + Logo
<script setup lang="ts">
import { RedeemCoupon } from 'redeem-coupon-ui'
import type { RedeemValidateResult } from 'redeem-coupon-ui'
import logoUrl from './logo.svg'
async function validateRedeemCode(code: string): Promise<RedeemValidateResult> {
/* ... */
}
</script>
<template>
<RedeemCoupon :validate-redeem-code="validateRedeemCode" :logo-url="logoUrl" />
</template>卡片 / 下载 / 成功文案
<script setup lang="ts">
import { RedeemCoupon } from 'redeem-coupon-ui'
import type { RedeemCardClickPayload, RedeemItem } from 'redeem-coupon-ui'
function onCardClick(p: RedeemCardClickPayload) {
window.open(p.item.detailUrl, '_blank')
}
function onDownload(items: RedeemItem[]) {
/* ... */
}
</script>
<template>
<RedeemCoupon
:validate-redeem-code="validateRedeemCode"
:on-card-click="onCardClick"
:on-download="onDownload"
>
<template #success-message="{ count }">已兑换 {{ count }} 项</template>
</RedeemCoupon>
</template>Exports
| 名称 | 说明 |
|------|------|
| RedeemCoupon | 主流程组件 |
| BorderGlow | 光效边框 |
| Stack | 卡片栈 |
| defaultEnrichItemsWithPosters | 库内置默认海报填充 |
类型:RedeemItem、RedeemValidateResult、RedeemCardClickPayload、EnrichItemsWithPosters、PosterRenderInput、PosterRenderResult 等(见包内 typings)。
Data types
validateRedeemCode 返回值:
type RedeemValidateResult =
| { ok: true; items: RedeemItem[] }
| { ok: false; message: string }RedeemItem 字段: id、title、price?、imageUrl、detailUrl(详情/分享链接,用于二维码与跳转)。
EnrichItemsWithPosters:
type EnrichItemsWithPosters = (
items: RedeemItem[],
context: { logoUrl?: string }
) => Promise<RedeemItem[]>