# PressConvertExchangeTemplate 兑换模板组件
# 📦 组件简介
PressConvertExchangeTemplate 是一个封装了兑换列表和积分消耗的模板组件,整合了 press-convert-exchange-list 和 press-convert-point-cost 两个子组件,提供了完整的积分兑换功能。
✨ 架构优势:
- Mixin 共享逻辑 - 避免重复代码
- 独立模板文件 - 支持不同的 DOM 结构
- Props 自动透传 - 使用
v-bind="{ ...$props, ...$attrs }"和显式事件转发 - 易于维护和扩展 - 修改逻辑只需改 mixin,修改结构只需改对应模板
# 🏗️ 架构设计
# 文件结构
press-convert-exchange-template/
├── press-convert-exchange-template.vue # 主组件(负责路由分发)
├── template-mixin.js # 公共逻辑 Mixin
├── pwd/
│ └── index.vue # PWD 模板(独立DOM结构)
├── party/
│ └── index.vue # Party 模板(独立DOM结构)
├── demo.vue # 示例代码
└── README.md # 使用文档
# 架构原理
┌─────────────────────────────────────────────┐
│ press-convert-exchange-template.vue │
│ (主组件 - 负责分发) │
│ │
│ <TemplatePwd v-if="type === 'pwd'" ... /> │
│ <TemplateParty v-else ... /> │
└──────────┬──────────────────────────────────┘
│
├─── type="pwd" ──→ pwd/index.vue (PWD模板)
│ ├─ mixins: [templateMixin]
│ ├─ 独立的 DOM 结构
│ └─ 独有 prop: pwdWrapBg
│
└─── type="party" ──→ party/index.vue (Party模板)
├─ mixins: [templateMixin]
└─ 独立的 DOM 结构
┌─────────────────────────────────────┐
│ template-mixin.js │
│ (公共逻辑 - 被所有模板共享) │
│ │
│ - props 定义 │
│ - emits 定义 │
│ - methods (事件处理) │
│ - components (子组件注册) │
└─────────────────────────────────────┘
# 模板布局结构
两个模板的 DOM 布局均为:
┌─────────────────────┐
│ point-cost │ ← 积分信息 + 刷新按钮
│ <slot /> │ ← 默认插槽(在积分区域内)
├─────────────────────┤
│ exchange-list │ ← 兑换商品列表
└─────────────────────┘
# 🎯 功能特性
- ✅ 支持 2 种预设模板(PWD/Party),每个模板有独立的 DOM 结构
- ✅ 兑换列表展示
- ✅ 积分信息显示
- ✅ 插槽扩展支持
- ✅ 事件回调处理
- ✅ Mixin 共享逻辑,避免代码重复
# 📖 使用方法
# 基础用法 - 使用 PWD 模板
<template>
<PressConvertExchangeTemplate
type="pwd"
:exchange-list="exchangeList"
:point-icon="pointIcon"
:point-info="pointInfo"
@exchangeClick="handleExchangeClick"
@showRewardExplain="handleShowRewardExplain"
@refresh="handleRefresh"
/>
</template>
<script>
import PressConvertExchangeTemplate from 'press-plus/press-convert-exchange-template/press-convert-exchange-template';
export default {
components: {
PressConvertExchangeTemplate,
},
data() {
return {
pointIcon: 'https://example.com/point-icon.png',
exchangeList: [
{
pic: 'https://example.com/reward.png',
name: '100元优惠券',
need_money: 1000,
num: 50,
showMoney: true,
btnTxt: '立即兑换',
disabled: false,
},
],
pointInfo: {
pointIcon: 'https://example.com/point-icon.png',
pointCount: 5000,
expireTime: '30天',
},
};
},
methods: {
handleExchangeClick(item) {
console.log('兑换商品:', item);
},
handleShowRewardExplain(index) {
console.log('显示奖励说明:', index);
},
handleRefresh() {
console.log('刷新积分');
},
},
};
</script>
# 切换不同模板
<!-- PWD 模板 - PWD 专属布局 -->
<PressConvertExchangeTemplate type="pwd" ... />
<!-- Party 模板 - Party 狂欢布局 -->
<PressConvertExchangeTemplate type="party" ... />
# 使用插槽
默认插槽位于 point-cost 组件内部(积分信息区域中)。
<PressConvertExchangeTemplate
type="pwd"
:exchange-list="exchangeList"
:point-icon="pointIcon"
:point-info="pointInfo"
>
<div class="custom-content">
<button @click="handleCustomAction">
查看更多奖励
</button>
</div>
</PressConvertExchangeTemplate>
# 📋 Props 属性
# 模板配置
| 属性名 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| type | String | 'pwd' | 模板类型:'pwd' / 'party' |
# 兑换列表相关
| 属性名 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| exchangeList | Array | [] | 兑换列表数据 |
| pointIcon | String | '' | 积分图标 URL |
| exchangeListBg | String | '' | 兑换列表背景图 |
| tagBg | String | '' | 兑换列表标签背景图 |
| redeemRewardBg | String | '' | 奖励框背景图 |
| rewardTextColor | String | '' | 奖励文字颜色 |
| rewardBtnBg | String | '' | 奖励按钮背景图 |
| rewardBtnTextColor | String | '' | 奖励按钮文字颜色 |
# 积分消耗相关
| 属性名 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| pointInfo | Object | {} | 积分信息对象 |
| pointTextColor | String | '' | 积分文字颜色 |
# PWD 模板独有
| 属性名 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| pwdWrapBg | String | '' | PWD 模板外层容器背景图 |
# exchangeList 数据结构
[
{
pic: 'https://example.com/reward.png', // 奖励图片
name: '100元优惠券', // 奖励名称
need_money: 1000, // 所需积分
num: 50, // 剩余数量
showMoney: true, // 是否显示积分
btnTxt: '立即兑换', // 按钮文字
disabled: false, // 是否禁用
}
]
# pointInfo 数据结构
{
pointIcon: 'https://example.com/point-icon.png', // 积分图标
pointCount: 5000, // 积分数量
expireTime: '30天', // 过期时间,显示为"X后失效",0表示不过期
}
# 🎪 Events 事件
| 事件名 | 参数 | 说明 |
|---|---|---|
| exchangeClick | item: Object | 点击兑换按钮时触发,返回兑换项数据 |
| showRewardExplain | index: Number | 点击奖励图片时触发,返回索引 |
| refresh | - | 点击刷新按钮时触发 |
# 🎨 Slots 插槽
| 插槽名 | 说明 |
|---|---|
| default | 默认插槽,位于 point-cost 积分信息区域内部 |
# 💡 模板差异说明
# PWD 模板 (pwd/index.vue)
布局:
积分信息(point-cost)
└─ <slot />
兑换列表(exchange-list)
特点:
- 支持
pwdWrapBg外层背景图 - 适合 PWD 活动场景
# Party 模板 (party/index.vue)
布局:
积分信息(point-cost)
└─ <slot />
兑换列表(exchange-list)
特点:
- 适合派对活动场景
# 🔧 扩展新模板
# 步骤 1:创建新模板目录和文件 festival/index.vue
<template>
<div class="press-exchange-festival">
<point-cost
:point-info="pointInfo"
:text-color="pointTextColor"
@refresh="handleRefresh"
>
<slot />
</point-cost>
<exchange-list
:exchange-list="exchangeList"
:point-icon="pointIcon"
:exchange-list-bg="exchangeListBg"
:tag-bg="tagBg"
:redeem-reward-bg="redeemRewardBg"
:reward-text-color="rewardTextColor"
:reward-btn-bg="rewardBtnBg"
:reward-btn-text-color="rewardBtnTextColor"
@exchangeClick="handleExchangeClick"
@showRewardExplain="handleShowRewardExplain"
/>
</div>
</template>
<script>
import templateMixin from '../template-mixin';
export default {
name: 'PressExchangeTemplateFestival',
mixins: [templateMixin],
};
</script>
# 步骤 2:在主组件中注册
// press-convert-exchange-template.vue
import TemplateFestival from './festival/index.vue';
export default {
components: {
TemplatePwd,
TemplateParty,
TemplateFestival,
},
props: {
type: {
validator: value => ['pwd', 'party', 'festival'].includes(value),
},
},
};
# 📝 注意事项
- 修改公共逻辑 - 修改
template-mixin.js会影响所有模板 - 修改模板结构 - 修改
pwd/index.vue或party/index.vue只影响对应模板 - Props 自动透传 - 主组件的 props 会自动传递给子模板
- 事件自动透传 - 子模板的事件会自动冒泡到主组件
- 图片 URL 需要是有效的网络地址或本地路径
- 建议在兑换前进行积分余额校验和库存校验
# 📦 依赖组件
press-convert-exchange-list- 兑换列表组件press-convert-point-cost- 积分消耗组件