Skip to content

Commit

Permalink
feat(Coupon): support for checkbox usage (#12744)
Browse files Browse the repository at this point in the history
  • Loading branch information
CatsAndMice authored Apr 6, 2024
1 parent a830c23 commit 3a524e8
Show file tree
Hide file tree
Showing 8 changed files with 196 additions and 27 deletions.
2 changes: 2 additions & 0 deletions packages/vant/docs/site/use-translate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ export function initDemoLocale() {
disabled: '禁用状态',
uneditable: '不可编辑',
basicUsage: '基础用法',
checkboxUsage: '多选用法',
usingUrl: '使用图片 URL',
advancedUsage: '高级用法',
loadingStatus: '加载状态',
Expand Down Expand Up @@ -80,6 +81,7 @@ export function initDemoLocale() {
disabled: 'Disabled',
uneditable: 'Uneditable',
basicUsage: 'Basic Usage',
checkboxUsage: 'Checkbox Usage',
usingUrl: 'Using URL',
advancedUsage: 'Advanced Usage',
loadingStatus: 'Loading',
Expand Down
45 changes: 33 additions & 12 deletions packages/vant/src/coupon-cell/CouponCell.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import {
truthProp,
makeArrayProp,
makeStringProp,
makeNumericProp,
createNamespace,
} from '../utils';

Expand All @@ -24,27 +23,47 @@ export const couponCellProps = {
editable: truthProp,
coupons: makeArrayProp<CouponInfo>(),
currency: makeStringProp('¥'),
chosenCoupon: makeNumericProp(-1),
chosenCoupon: {
type: [Number, Array],
default: -1,
},
};

export type CouponCellProps = ExtractPropTypes<typeof couponCellProps>;

function formatValue({ coupons, chosenCoupon, currency }: CouponCellProps) {
const coupon = coupons[+chosenCoupon];

if (coupon) {
const getValue = (coupon: CouponInfo) => {
let value = 0;

const { value: couponValue, denominations } = coupon;
if (isDef(coupon.value)) {
({ value } = coupon);
value = couponValue;
} else if (isDef(coupon.denominations)) {
value = coupon.denominations;
value = denominations as number;
}
return value;
};

return `-${currency} ${(value / 100).toFixed(2)}`;
let value = 0,
isExist = false;
if (Array.isArray(chosenCoupon)) {
(chosenCoupon as CouponInfo[]).forEach((i) => {
const coupon = coupons[+i];
if (coupon) {
isExist = true;
value += getValue(coupon);
}
});
} else {
const coupon = coupons[+chosenCoupon];
if (coupon) {
isExist = true;
value = getValue(coupon);
}
}

return coupons.length === 0 ? t('noCoupon') : t('count', coupons.length);
if (!isExist) {
return coupons.length === 0 ? t('noCoupon') : t('count', coupons.length);
}
return `-${currency} ${(value / 100).toFixed(2)}`;
}

export default defineComponent({
Expand All @@ -54,7 +73,9 @@ export default defineComponent({

setup(props) {
return () => {
const selected = props.coupons[+props.chosenCoupon];
const selected = Array.isArray(props.chosenCoupon)
? props.chosenCoupon.length
: props.coupons[+props.chosenCoupon];
return (
<Cell
class={bem()}
Expand Down
55 changes: 43 additions & 12 deletions packages/vant/src/coupon-list/CouponList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
computed,
nextTick,
onMounted,
unref,
defineComponent,
type ExtractPropTypes,
} from 'vue';
Expand Down Expand Up @@ -37,7 +38,7 @@ export const couponListProps = {
currency: makeStringProp('¥'),
showCount: truthProp,
emptyImage: String,
chosenCoupon: makeNumberProp(-1),
chosenCoupon: [Number, Array],
enabledTitle: String,
disabledTitle: String,
disabledCoupons: makeArrayProp<CouponInfo>(),
Expand Down Expand Up @@ -137,6 +138,19 @@ export default defineComponent({
const count = props.showCount ? ` (${coupons.length})` : '';
const title = (props.enabledTitle || t('enable')) + count;

const getChosenCoupon = (
chosenCoupon: Array<any> = [],
value: number = 0,
): Array<any> => {
const unrefChosenCoupon = unref(chosenCoupon);
const index = unrefChosenCoupon.indexOf(value);
if (index === -1) {
return [...unrefChosenCoupon, value];
}
unrefChosenCoupon.splice(index, 1);
return [...unrefChosenCoupon];
};

return (
<Tab title={title}>
<div
Expand All @@ -148,9 +162,20 @@ export default defineComponent({
key={coupon.id}
ref={setCouponRefs(index)}
coupon={coupon}
chosen={index === props.chosenCoupon}
chosen={
Array.isArray(props.chosenCoupon)
? props.chosenCoupon.includes(index)
: index === props.chosenCoupon
}
currency={props.currency}
onClick={() => emit('change', index)}
onClick={() =>
emit(
'change',
Array.isArray(props.chosenCoupon)
? getChosenCoupon(props.chosenCoupon, index)
: index,
)
}
/>
))}
{!coupons.length && renderEmpty()}
Expand Down Expand Up @@ -210,15 +235,21 @@ export default defineComponent({
{renderDisabledTab()}
</Tabs>
<div class={bem('bottom')}>
<Button
v-show={props.showCloseButton}
round
block
type="primary"
class={bem('close')}
text={props.closeButtonText || t('close')}
onClick={() => emit('change', -1)}
/>
{slots['list-button'] ? (
slots['list-button']()
) : (
<Button
v-show={props.showCloseButton}
round
block
type="primary"
class={bem('close')}
text={props.closeButtonText || t('close')}
onClick={() =>
emit('change', Array.isArray(props.chosenCoupon) ? [] : -1)
}
/>
)}
</div>
</div>
);
Expand Down
3 changes: 2 additions & 1 deletion packages/vant/src/coupon-list/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ export default {
| Attribute | Description | Type | Default |
| --- | --- | --- | --- |
| v-model | Current exchange code | _string_ | - |
| chosen-coupon | Index of chosen coupon | _number_ | `-1` |
| chosen-coupon | Index of chosen coupon,support multiple selection(type `[]`) | _number\|number[]_ | `-1` |
| coupons | Coupon list | _CouponInfo[]_ | `[]` |
| disabled-coupons | Disabled coupon list | _CouponInfo[]_ | `[]` |
| enabled-title | Title of coupon list | _string_ | `Available` |
Expand Down Expand Up @@ -133,6 +133,7 @@ export default {
| -------------------- | ------------------------------- |
| list-footer | Coupon list bottom |
| disabled-list-footer | Unavailable coupons list bottom |
| list-button | Customize the bottom button |

### Data Structure of CouponInfo

Expand Down
3 changes: 2 additions & 1 deletion packages/vant/src/coupon-list/README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ export default {
| 参数 | 说明 | 类型 | 默认值 |
| --- | --- | --- | --- |
| v-model:code | 当前输入的兑换码 | _string_ | - |
| chosen-coupon | 当前选中优惠券的索引 | _number_ | `-1` |
| chosen-coupon | 当前选中优惠券的索引,支持多选(类型为`[]` | _number\|number[]_ | `-1` |
| coupons | 可用优惠券列表 | _CouponInfo[]_ | `[]` |
| disabled-coupons | 不可用优惠券列表 | _CouponInfo[]_ | `[]` |
| enabled-title | 可用优惠券列表标题 | _string_ | `可使用优惠券` |
Expand Down Expand Up @@ -135,6 +135,7 @@ export default {
| -------------------- | -------------------- |
| list-footer | 优惠券列表底部 |
| disabled-list-footer | 不可用优惠券列表底部 |
| list-button | 自定义底部按钮 |

### CouponInfo 数据结构

Expand Down
49 changes: 48 additions & 1 deletion packages/vant/src/coupon-list/demo/index.vue
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
<script setup lang="ts">
import VanCouponCell from '../../coupon-cell';
import VanPopup from '../../popup';
import VanButton from '../../button';
import VanCouponList from '..';
import { ref, computed } from 'vue';
import { ref, computed, unref } from 'vue';
import { useTranslate } from '../../../docs/site';
import { CouponInfo } from '../../coupon';
import { showToast } from '../../toast';
Expand Down Expand Up @@ -30,7 +31,10 @@ const getRandomId = (max = 999999) =>
String(Math.floor(Math.random() * max) + 1);
const showList = ref(false);
const showListArray = ref(false);
const chosenCoupon = ref(-1);
const chosenCouponArray = ref([]);
const chosenCouponArrayResult = ref([]);
const exchangedCoupons = ref<CouponInfo[]>([]);
const coupon = computed(() => ({
Expand Down Expand Up @@ -84,6 +88,15 @@ const onChange = (index: number) => {
chosenCoupon.value = index;
};
const onChangeArray = (chosenCoupon: []) => {
chosenCouponArray.value = chosenCoupon;
};
const onSubmit = () => {
showListArray.value = false;
chosenCouponArrayResult.value = unref(chosenCouponArray);
};
const onExchange = () => {
showToast(t('exchange'));
exchangedCoupons.value.push({
Expand Down Expand Up @@ -115,4 +128,38 @@ const onExchange = () => {
/>
</van-popup>
</demo-block>

<demo-block :title="t('checkboxUsage')">
<van-coupon-cell
:coupons="coupons"
:chosen-coupon="chosenCouponArrayResult"
@click="showListArray = true"
/>
<van-popup
v-model:show="showListArray"
round
position="bottom"
style="height: 90%; padding-top: 4px"
>
<van-coupon-list
:coupons="coupons"
:chosen-coupon="chosenCouponArray"
:disabled-coupons="disabledCoupons"
:show-close-button="false"
@change="onChangeArray"
@exchange="onExchange"
>
<template #list-button>
<van-button
round
block
type="primary"
text="确定"
style="height: 40px"
@click="onSubmit"
/>
</template>
</van-coupon-list>
</van-popup>
</demo-block>
</template>
Original file line number Diff line number Diff line change
@@ -1,6 +1,36 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html

exports[`should render demo and match snapshot 1`] = `
<!--[-->
<div>
<!--[-->
<div
class="van-cell van-cell--clickable van-coupon-cell"
role="button"
tabindex="0"
>
<div
class="van-cell__title"
style
>
<span>
Coupon
</span>
</div>
<div class="van-cell__value van-coupon-cell__value">
<span>
You have 2 coupons
</span>
</div>
<i
class="van-badge__wrapper van-icon van-icon-arrow van-cell__right-icon"
style
>
<!--[-->
</i>
</div>
<!--[-->
</div>
<div>
<!--[-->
<div
Expand Down
36 changes: 36 additions & 0 deletions packages/vant/src/coupon-list/test/__snapshots__/demo.spec.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,40 @@ exports[`should render demo and match snapshot 1`] = `
>
</transition-stub>
</div>
<div>
<div
class="van-cell van-cell--clickable van-coupon-cell"
role="button"
tabindex="0"
>
<div class="van-cell__title">
<span>
Coupon
</span>
</div>
<div class="van-cell__value van-coupon-cell__value">
<span>
You have 2 coupons
</span>
</div>
<i class="van-badge__wrapper van-icon van-icon-arrow van-cell__right-icon">
</i>
</div>
<transition-stub
name="van-fade"
appear="true"
persisted="false"
css="true"
role="button"
tabindex="0"
>
</transition-stub>
<transition-stub
name="van-popup-slide-bottom"
appear="false"
persisted="false"
css="true"
>
</transition-stub>
</div>
`;

0 comments on commit 3a524e8

Please sign in to comment.