尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Vant CouponList 优惠券列表组件完全指南:兑换、选择与主题定制

Vant CouponList 优惠券列表组件完全指南:兑换、选择与主题定制 Vant CouponList 优惠券列表组件完全指南兑换、选择与主题定制【免费下载链接】vantA lightweight, customizable Vue UI library for mobile web apps.项目地址: https://gitcode.com/GitHub_Trending/va/vant导读本文围绕 Vant 移动端 UI 库中的CouponList优惠券列表与配套的CouponCell优惠券单元格两个组件展开系统讲解如何在 Vue 3 项目中实现优惠券的兑换、选择、失效券展示与弹层交互。读完本文你将掌握两个组件的完整 API、CouponInfo 数据结构、多选模式与兑换流程的实现细节并能够通过 CSS 变量与插槽完成深度定制。文中所有结论均以当前仓库源码CouponList.tsx、Coupon.tsx、index.less与测试用例index.spec.ts为佐证。组件概览CouponCell 与 CouponList 的分工在 Vant 的优惠券方案中两个组件各司其职CouponCell一个「入口」单元格常放在结算页等位置用于展示当前已选优惠券的面额汇总例如-¥ 1.50或在未选择时展示「暂无可用优惠券」。它本身不承载选择交互点击后通常由业务方打开弹层。CouponList一个「容器」组件内部使用Tabs组织「可用 / 不可用」两个 Tab内置兑换输入框、兑换按钮、优惠券卡片列表以及底部关闭/确认按钮是完整的选择与兑换交互单元。从仓库目录结构看两者分属独立模块优惠券列表位于 coupon-list入口单元格位于 coupon-cell而承载单张优惠券卡片渲染的是 coupon其中导出了CouponInfo类型。三者组合即构成完整业务闭环。安装与注册在 Vue 3 项目中通过app.use全局注册组件即可import { createApp } from vue; import { CouponCell, CouponList } from vant; const app createApp(); app.use(CouponCell); app.use(CouponList);注册后即可在模板中使用van-coupon-cell与van-coupon-list。除全局注册外也可按需引入、局部注册更多注册方式可参考 组件注册文档。从 coupon-list/index.ts 的源码可以看到CouponList通过withInstall包装后导出同时导出了couponListProps与CouponListProps类型并声明了VanCouponList全局组件类型。快速上手基础用法完整示例CouponList 的标准用法是配合 Popup 弹层使用点击 CouponCell 打开弹层弹层内嵌入 CouponList用户选择或兑换后通过事件回调更新状态。以下示例直接取自官方 Demodemo/index.vue的简化形态!-- Coupon Cell -- van-coupon-cell :couponscoupons :chosen-couponchosenCoupon clickshowList true / !-- Coupon List -- van-popup v-model:showshowList round positionbottom styleheight: 90%; padding-top: 4px; van-coupon-list :couponscoupons :chosen-couponchosenCoupon :disabled-couponsdisabledCoupons changeonChange exchangeonExchange / /van-popupimport { ref } from vue; export default { setup() { const coupon { available: 1, originCondition: 0, reason: , value: 150, name: Coupon name, startAt: 1489104000, endAt: 1514592000, valueDesc: 1.5, unitDesc: 元, }; const coupons ref([coupon]); const showList ref(false); const chosenCoupon ref(-1); const onChange (index) { showList.value false; chosenCoupon.value index; }; const onExchange (code) { coupons.value.push(coupon); }; return { coupons, showList, onChange, onExchange, chosenCoupon, disabledCoupons: [coupon], }; }, };这段示例透露了几个关键约定chosenCoupon初始为-1表示未选中任何优惠券onChange回调携带所选优惠券的索引业务方在此关闭弹层并更新选中态onExchange回调携带用户输入的兑换码业务方据此向后端发起兑换成功后把新券push进coupons列表即可让新券立即出现在列表中——这是官方 Demo 中演示的「兑换成功后券立即生效」的典型流程。卡片展示优先级CouponList 中的每张券卡片由 Coupon.tsx 渲染其「面值展示」存在明确的优先级faceAmount计算属性若提供valueDesc直接展示该文案如1.5 元、8.8 折并拼接unitDesc单位否则若提供denominations展示currency denominations / 100金额按分存储否则若提供discount展示折算后的折扣文案discount / 10如88渲染为8.8 折。而「使用条件」文案同样有兜底逻辑优先使用coupon.condition否则根据originCondition自动生成「满 X 减」或「无门槛」文案见 coupon/utils.ts 中的formatAmount、formatDiscount、getDate工具函数。getDate将秒级时间戳格式化为YYYY.MM.DD形式的有效期展示。CouponCell Props 详解CouponCell 的入口展示逻辑在 CouponCell.tsx 中实现其 Props 如下属性说明类型默认值title单元格标题stringCouponchosen-coupon已选优惠券索引number | number[]-1coupons优惠券列表Coupon[][]editable单元格是否可编辑决定是否显示箭头booleantrueborder是否显示内边框booleantruecurrency货币符号string¥从源码可以看到 CouponCell 的「值」展示策略formatValue有已选券时将所选券的value或denominations累加渲染为-¥ xxx.xx的汇总金额金额按「分」存储除以 100 后保留两位小数无已选券但列表非空时渲染「共 N 张可用优惠券」列表为空时渲染「暂无可用优惠券」。因此 CouponCell 天然适合作为结算页的「优惠券入口」让用户在下单前一眼看到优惠汇总。CouponList Props 详解CouponList 的 Props 完整定义位于 CouponList.tsx 的couponListProps中与文档 API 表一一对应属性说明类型默认值v-model当前兑换码string-chosen-coupon已选优惠券索引支持多选类型为数组[]number | number[]-1coupons可用优惠券列表CouponInfo[][]disabled-coupons不可用优惠券列表CouponInfo[][]enabled-title可用券列表标题stringAvailabledisabled-title不可用券列表标题stringUnavailableexchange-button-text兑换按钮文案stringExchangeexchange-button-loading兑换按钮是否显示加载中booleanfalseexchange-button-disabled是否禁用兑换按钮booleanfalseexchange-min-length兑换码最短长度达到后才可点击兑换number1displayed-coupon-index需要滚动定位到的优惠券索引number-close-button-text底部关闭按钮文案stringCloseinput-placeholder兑换码输入框占位文案stringCoupon codecurrency货币符号string¥empty-image列表为空时的占位图string-show-count是否在 Tab 标题中展示优惠券数量booleantrue兑换按钮的禁用逻辑源码级解读兑换按钮是否可用由 CouponList.tsx 中的buttonDisabled计算属性决定const buttonDisabled computed( () !props.exchangeButtonLoading (props.exchangeButtonDisabled || !currentCode.value || currentCode.value.length props.exchangeMinLength), );即只要「非加载中」且exchangeButtonDisabled为 true或兑换码为空或兑换码长度小于exchangeMinLength按钮即被禁用。这解释了exchange-min-length的语义用于防止用户输入过短的无效兑换码。兑换流程与 v-model 行为用户点击兑换按钮时触发onExchangeCouponList.tsxconst onExchange () { emit(exchange, currentCode.value); // auto clear currentCode when not use v-model if (!props.code) { currentCode.value ; } };一个容易被忽略的细节是如果不传v-model即props.code为空兑换成功后输入框会自动清空如果传了v-model则清空逻辑交由业务方控制。同时源码通过watch(currentCode, (value) emit(update:code, value))将输入实时同步给v-model并在外部code变化时反向更新内部状态保证受控与非受控两种用法都能正常工作。多选模式当chosen-coupon传入数组时组件自动切换为多选模式每次点击可用券卡片change事件会携带新的索引数组updateChosenCoupon逻辑若索引已在数组中则移除否则追加见 CouponList.tsx底部关闭按钮点击时多选模式发射change: []单选模式发射change: -1见 CouponList.tsx。官方 Demodemo/index.vue提供了完整的多选示例配合:show-close-buttonfalse隐藏默认关闭按钮改用自定义的「确定」按钮通过list-button插槽提交多选结果。注意多选模式下chosenCoupon数组同时传给 CouponCell 时CouponCell 会汇总多张券的金额并求和展示。列表高度与自动滚动组件在挂载及窗口高度变化时会调用updateListHeightCouponList.tsx动态计算列表滚动区高度根容器高度减去兑换栏高度与 44px 的 Tabs 高度保证列表在弹层内正确滚动。而displayed-coupon-index则会在挂载后或变化时通过scrollIntoView自动滚动定位到指定优惠券适合「结算页回显上次选择位置」的场景。CouponList Events事件说明回调参数change已选优惠券变化时触发index所选优惠券的索引多选模式下为索引数组exchange点击兑换按钮时触发code用户输入的兑换码测试用例index.spec.ts对这两个事件的行为有明确验证未输入兑换码时点击兑换按钮不会触发exchange输入1后点击触发exchange且参数为[1]传入codeprop 后点击则携带对应值。update:code事件的触发顺序也在测试中被断言输入时先触发update:code随后非受控模式下再触发一次空串清空。CouponList Slots插槽名说明list-footer可用优惠券列表底部内容disabled-list-footer不可用优惠券列表底部内容list-button自定义底部按钮替换默认的关闭按钮从源码CouponList.tsx可以看到前两个插槽分别渲染在「可用 / 不可用」两个 Tab 的列表末尾list-button插槽存在时完全替换底部默认的关闭按钮区域。测试用例验证了list-footer与disabled-list-footer两个插槽在不同 Tab 下的渲染结果。CouponInfo 数据结构文档 API 表给出的基础字段如下字段说明类型id优惠券唯一标识stringname优惠券名称stringcondition使用条件文案stringstartAt生效时间秒级时间戳numberendAt失效时间秒级时间戳numberdescription优惠券描述stringreason不可用原因stringvalue优惠券面值单位分numbervalueDesc面值展示文案stringunitDesc面值单位文案string结合 Coupon.tsx 中导出的CouponInfo类型定义实际还支持以下可选字段字段说明类型discount折扣值88 表示 8.8 折numberdenominations券面金额单位分numberoriginCondition原始使用门槛单位分用于生成「无门槛 / 满减」文案number从测试数据index.spec.ts可以看到这些字段的典型组合value: 150, denominations: 150表示 1.5 元现金券discount: 88表示 8.8 折折扣券reason字段则用于在「不可用」Tab 中展示失效原因见 Coupon.tsx 的description计算逻辑不可用券优先展示reason否则展示description。类型定义CouponList 组件导出了完整的 TypeScript 类型可直接在业务代码中引入import type { CouponCellProps, CouponListProps, CouponInfo } from vant;此外 coupon-list/types.ts 中还导出了CouponListThemeVars类型用于主题变量配置的类型约束。主题定制CSS 变量组件通过 CSS 变量支持主题定制可结合 ConfigProvider 组件 统一配置。文档列出的变量如下变量名默认值说明--van-coupon-margin0 var(--van-padding-sm) var(--van-padding-sm)优惠券外边距--van-coupon-content-height84px优惠券内容高度--van-coupon-content-padding14px 0优惠券内容内边距--van-coupon-content-text-colorvar(--van-text-color)优惠券内容文字颜色--van-coupon-backgroundvar(--van-background-2)优惠券背景色--van-coupon-active-backgroundvar(--van-active-color)优惠券按压背景色--van-coupon-radiusvar(--van-radius-lg)优惠券圆角--van-coupon-shadow0 0 4px rgba(0, 0, 0, 0.1)优惠券阴影--van-coupon-head-width96px优惠券头部面值区宽度--van-coupon-amount-colorvar(--van-danger-color)面值金额颜色--van-coupon-amount-font-size30px面值金额字号--van-coupon-currency-font-size40%货币符号字号比例--van-coupon-name-font-sizevar(--van-font-size-md)优惠券名称字号--van-coupon-disabled-text-colorvar(--van-text-color-2)不可用券文字颜色--van-coupon-description-paddingvar(--van-padding-xs) var(--van-padding-md)描述区内边距--van-coupon-description-border-colorvar(--van-border-color)描述区分隔线颜色--van-coupon-checkbox-colorvar(--van-danger-color)选中复选框颜色--van-coupon-list-backgroundvar(--van-background)列表背景色--van-coupon-list-field-padding5px 0 5px var(--van-padding-md)兑换输入框内边距--van-coupon-list-exchange-button-height32px兑换按钮高度--van-coupon-list-close-button-height40px关闭按钮高度--van-coupon-list-empty-tip-colorvar(--van-text-color-2)空列表提示文字颜色--van-coupon-list-empty-tip-font-sizevar(--van-font-size-md)空列表提示字号--van-coupon-list-empty-tip-line-heightvar(--van-line-height-md)空列表提示行高--van-coupon-cell-selected-text-colorvar(--van-text-color)CouponCell 选中态文字颜色需要说明的是文档表格中的默认值以组件文档为准而从当前仓库的样式文件看coupon/index.less 中--van-coupon-amount-color与--van-coupon-checkbox-color的实际默认值为var(--van-primary-color)coupon-list/index.less 中定义了coupon-list前缀的 6 个变量。实际定制时建议以当前安装版本对应的样式文件为准通过 ConfigProvider 或直接覆盖变量即可全局生效。源码与测试验证组件行为一览除了上文已穿插的源码证据CouponList 的行为还可在测试中直接验证coupon-list/test/index.spec.ts快照渲染多张不同形态的券空券、现金券、折扣券、不可用券的渲染结果与快照一致空列表coupons与disabledCoupons均为空时两个 Tab 都会渲染空状态自定义占位图empty-image传入自定义 URL 时空状态使用该图片兑换事件输入兑换码前后的exchange事件触发差异、update:code事件序列均有断言插槽渲染list-footer与disabled-list-footer在对应 Tab 中的渲染结果有快照覆盖。这些测试与 demo/index.vue 共同构成了组件的「行为契约」也是你集成 CouponList 时可以参照的可靠范例。结语Vant 的 CouponList 与 CouponCell 组合覆盖了移动端优惠券业务的核心链路入口汇总展示CouponCell→ 弹层选择/兑换CouponList→ 状态回传change / exchange 事件。通过chosen-coupon的数组形态可无缝切换到多选场景list-button插槽可替换为自定义确认按钮CSS 变量则可满足品牌化的视觉定制。结合本文提供的源码路径与测试用例你可以在当前仓库中进一步深挖每个参数背后的实现细节为业务集成提供精确依据。【免费下载链接】vantA lightweight, customizable Vue UI library for mobile web apps.项目地址: https://gitcode.com/GitHub_Trending/va/vant创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表