feat(Sku): add new startSaleNum prop (#5105)

This commit is contained in:
Waiter 2019-11-28 10:51:27 +08:00 committed by neverland
parent d8e30bdcac
commit 17472e04c5
8 changed files with 132 additions and 42 deletions

View File

@ -141,6 +141,7 @@ export default {
| message-config | Message related config | *object* | `{}` | - |
| get-container | Return the mount node for sku | *string \| () => Element* | - | - |
| safe-area-inset-bottom | Whether to enable bottom safe area adaptation | *boolean* | `false` | 2.2.1 |
| start-sale-num | Minimum quantity | *number* | `1` | 2.2.15 |
### Events
@ -258,10 +259,10 @@ customStepperConfig: {
quotaText: 'only 5 can buy',
// custom callback when over limit
handleOverLimit: (data) => {
const { action, limitType, quota, quotaUsed } = data;
const { action, limitType, quota, quotaUsed, startSaleNum } = data;
if (action === 'minus') {
Toast('at least select one');
Toast(`at least select ${startSaleNum > 1 ? startSaleNum : 'one'}`);
} else if (action === 'plus') {
// const { LIMIT_TYPE } = Sku.skuConstants;
if (limitType === LIMIT_TYPE.QUOTA_LIMIT) {

View File

@ -145,6 +145,7 @@ export default {
| initial-sku | 默认选中的 sku具体参考高级用法 | *object* | `{}` | - |
| show-soldout-sku | 是否展示售罄的 sku默认展示并置灰 | *boolean* | `true` | - |
| safe-area-inset-bottom | 是否开启底部安全区适配,[详细说明](#/zh-CN/quickstart#di-bu-an-quan-qu-gua-pei) | *boolean* | `false` | 2.2.1 |
| start-sale-num | 起售数量 | *number* | `1` | 2.2.15 |
### Events
@ -270,10 +271,10 @@ customStepperConfig: {
quotaText: '每次限购xxx件',
// 自定义步进器超过限制时的回调
handleOverLimit: (data) => {
const { action, limitType, quota, quotaUsed } = data;
const { action, limitType, quota, quotaUsed, startSaleNum } = data;
if (action === 'minus') {
Toast('至少选择一件商品');
Toast(startSaleNum > 1 ? `${startSaleNum}件起售` : '至少选择一件商品');
} else if (action === 'plus') {
// const { LIMIT_TYPE } = Sku.skuConstants;
if (limitType === LIMIT_TYPE.QUOTA_LIMIT) {

View File

@ -45,6 +45,10 @@ export default createComponent({
type: Number,
default: 0
},
startSaleNum: {
type: Number,
default: 1
},
initialSku: {
type: Object,
default: () => ({})
@ -236,22 +240,6 @@ export default createComponent({
];
},
quotaText() {
const { quotaText, hideQuotaText } = this.customStepperConfig;
if (hideQuotaText) return '';
let text = '';
if (quotaText) {
text = quotaText;
} else if (this.quota > 0) {
text = t('quotaLimit', this.quota);
}
return text;
},
selectedText() {
if (this.selectedSkuComb) {
return `${t('selected')} ${this.selectedSkuValues.map(item => item.name).join('')}`;
@ -274,6 +262,7 @@ export default createComponent({
skuEventBus.$on('sku:numChange', this.onNumChange);
skuEventBus.$on('sku:previewImage', this.onPreviewImage);
skuEventBus.$on('sku:overLimit', this.onOverLimit);
skuEventBus.$on('sku:stepperState', this.onStepperState);
skuEventBus.$on('sku:addCart', this.onAddCart);
skuEventBus.$on('sku:buy', this.onBuy);
@ -289,6 +278,8 @@ export default createComponent({
const { skuStepper } = this.$refs;
const { selectedNum } = this.initialSku;
const num = isDef(selectedNum) ? selectedNum : 1;
// 用来缓存不合法的情况
this.stepperError = null;
if (skuStepper) {
skuStepper.setCurrentNum(num);
@ -409,18 +400,35 @@ export default createComponent({
}
if (action === 'minus') {
Toast(t('minusTip'));
if (this.startSaleNum > 1) {
Toast(t('minusStartTip', this.startSaleNum));
} else {
Toast(t('minusTip'));
}
} else if (action === 'plus') {
if (limitType === QUOTA_LIMIT) {
let msg = t('quotaLimit', quota);
if (quotaUsed > 0) msg += `${t('quotaCount', quotaUsed)}`;
Toast(msg);
if (quotaUsed > 0) {
Toast(t('quotaUsedTip', quota, quotaUsed));
} else {
Toast(t('quotaTip', quota));
}
} else {
Toast(t('soldout'));
}
}
},
onStepperState(data) {
if (data.valid) {
this.stepperError = null;
} else {
this.stepperError = {
...data,
action: 'plus',
};
}
},
onAddCart() {
this.onBuyOrAddCart('add-cart');
},
@ -430,6 +438,10 @@ export default createComponent({
},
onBuyOrAddCart(type) {
// 有信息表示该sku根本不符合购买条件
if (this.stepperError) {
return this.onOverLimit(this.stepperError);
}
const error = this.validateSku();
if (error) {
Toast(error);
@ -463,7 +475,6 @@ export default createComponent({
selectedSku,
selectedNum,
stepperTitle,
hideQuotaText,
selectedSkuComb
} = this;
@ -494,7 +505,6 @@ export default createComponent({
{!this.hideStock && (
<SkuHeaderItem>
<span class="van-sku__stock">{this.stockText}</span>
{!hideQuotaText && this.quotaText && <span class="van-sku__quota">({this.quotaText})</span>}
</SkuHeaderItem>
)}
{this.hasSku && !this.hideSelectedText && (
@ -530,6 +540,7 @@ export default createComponent({
stock={this.stock}
quota={this.quota}
quotaUsed={this.quotaUsed}
startSaleNum={this.startSaleNum}
skuEventBus={skuEventBus}
selectedNum={selectedNum}
selectedSku={selectedSku}
@ -537,6 +548,7 @@ export default createComponent({
skuStockNum={sku.stock_num}
disableStepperInput={this.disableStepperInput}
customStepperConfig={this.customStepperConfig}
hideQuotaText={this.hideQuotaText}
onChange={event => {
this.$emit('stepper-change', event);
}}

View File

@ -16,6 +16,7 @@ export default createComponent({
stepperTitle: String,
disableStepperInput: Boolean,
customStepperConfig: Object,
hideQuotaText: Boolean,
quota: {
type: Number,
default: 0
@ -23,7 +24,11 @@ export default createComponent({
quotaUsed: {
type: Number,
default: 0
}
},
startSaleNum: {
type: Number,
default: 1,
},
},
data() {
@ -40,9 +45,17 @@ export default createComponent({
},
stepperLimit(limit) {
if (limit < this.currentNum) {
if (limit < this.currentNum && this.stepperMinLimit <= limit) {
this.currentNum = limit;
}
this.checkState(this.stepperMinLimit, limit);
},
stepperMinLimit(start) {
if (start > this.currentNum || start > this.stepperLimit) {
this.currentNum = start;
}
this.checkState(start, this.stepperLimit);
}
},
@ -62,7 +75,35 @@ export default createComponent({
}
return limit;
}
},
stepperMinLimit() {
return this.startSaleNum < 1 ? 1 : this.startSaleNum;
},
quotaText() {
const { quotaText, hideQuotaText } = this.customStepperConfig;
if (hideQuotaText) return '';
let text = '';
if (quotaText) {
text = quotaText;
} else {
const textArr = [];
if (this.startSaleNum > 1) {
textArr.push(t('quotaStart', this.startSaleNum));
}
if (this.quota > 0) {
textArr.push(t('quotaLimit', this.quota));
}
text = textArr.join(t('comma'));
}
return text;
},
},
created() {
this.checkState(this.stepperMinLimit, this.stepperLimit);
},
methods: {
@ -75,7 +116,8 @@ export default createComponent({
action,
limitType: this.limitType,
quota: this.quota,
quotaUsed: this.quotaUsed
quotaUsed: this.quotaUsed,
startSaleNum: this.startSaleNum,
});
},
@ -83,7 +125,27 @@ export default createComponent({
const { handleStepperChange } = this.customStepperConfig;
handleStepperChange && handleStepperChange(currentValue);
this.$emit('change', currentValue);
}
},
checkState(min, max) {
// 如果选择小于起售,则强制变为起售
if (this.currentNum < min || min > max) {
this.currentNum = min;
} else if (this.currentNum > max) {
// 当前选择数量大于最大可选时,需要重置已选数量
this.currentNum = max;
}
this.skuEventBus.$emit('sku:stepperState', {
valid: min <= max,
min,
max,
limitType: this.limitType,
quota: this.quota,
quotaUsed: this.quotaUsed,
startSaleNum: this.startSaleNum,
});
},
},
render() {
@ -94,11 +156,13 @@ export default createComponent({
<Stepper
vModel={this.currentNum}
class="van-sku__stepper"
min={this.stepperMinLimit}
max={this.stepperLimit}
disableInput={this.disableStepperInput}
onOverlimit={this.onOverLimit}
onChange={this.onChange}
/>
{!this.hideQuotaText && this.quotaText && <span class="van-sku__stepper-quota">({this.quotaText})</span>}
</div>
</div>
);

View File

@ -2,6 +2,7 @@ export default {
goods_id: '946755',
quota: 15,
quota_used: 0,
start_sale_num: 10,
goods_info: {
title: '测试商品',
picture:

View File

@ -11,6 +11,7 @@
:hide-stock="skuData.sku.hide_stock"
:quota="skuData.quota"
:quota-used="skuData.quota_used"
:start-sale-num="skuData.start_sale_num"
:close-on-click-overlay="closeOnClickOverlay"
:message-config="messageConfig"
:custom-sku-validator="customSkuValidator"
@ -42,6 +43,7 @@
:hide-stock="skuData.sku.hide_stock"
:quota="skuData.quota"
:quota-used="skuData.quota_used"
:start-sale-num="skuData.start_sale_num"
:custom-stepper-config="customStepperConfig"
:message-config="messageConfig"
hide-quota-text
@ -70,6 +72,7 @@
:hide-stock="skuData.sku.hide_stock"
:quota="skuData.quota"
:quota-used="skuData.quota_used"
:start-sale-num="skuData.start_sale_num"
:custom-stepper-config="customStepperConfig"
:message-config="messageConfig"
:show-soldout-sku="false"
@ -99,6 +102,7 @@
:hide-stock="skuData.sku.hide_stock"
:quota="skuData.quota"
:quota-used="skuData.quota_used"
:start-sale-num="skuData.start_sale_num"
show-add-cart-btn
reset-stepper-on-hide
safe-area-inset-bottom
@ -126,7 +130,7 @@
square
size="large"
type="danger"
@click="props.skuEventBus.$emit('sku:buy')"
@click="skuEventBus.$emit('sku:buy')"
>
{{ $t('button2') }}
</van-button>
@ -185,10 +189,10 @@ export default {
quotaText: '单次限购100件',
stockFormatter: (stock) => `剩余${stock}`,
handleOverLimit: (data) => {
const { action, limitType, quota } = data;
const { action, limitType, quota, startSaleNum = 1 } = data;
if (action === 'minus') {
this.$toast('至少选择一件商品');
this.$toast(startSaleNum > 1 ? `${startSaleNum}件起售` : '至少选择一件商品');
} else if (action === 'plus') {
if (limitType === LIMIT_TYPE.QUOTA_LIMIT) {
this.$toast(`限购${quota}`);

View File

@ -198,6 +198,7 @@
&-container {
height: 30px;
margin-right: 20px;
overflow: hidden;
}
}
@ -208,6 +209,14 @@
float: left;
line-height: 30px;
}
&-quota {
display: inline-block;
float: right;
color: @red;
font-size: @font-size-sm;
line-height: 30px;
}
}
&__stock {
@ -221,12 +230,6 @@
}
}
&__quota {
display: inline-block;
color: @red;
font-size: @font-size-sm;
}
&-messages {
padding-bottom: @padding-xl;

View File

@ -11,11 +11,12 @@ export default {
soldout: '库存不足',
originPrice: '原价',
minusTip: '至少选择一件',
minusStartTip: (start: number) => `${start}件起售`,
unavailable: '商品已经无法购买啦',
stock: '剩余',
stockUnit: '件',
quotaLimit: (quota: number) => `每人限购${quota}`,
quotaCount: (count: number) => `你已购买${count}`
quotaTip: (quota: number) => `每人限购${quota}`,
quotaUsedTip: (quota: number, count: number) => `每人限购${quota}件,你已购买${count}`
},
vanSkuActions: {
buy: '立即购买',
@ -26,6 +27,9 @@ export default {
fail: '上传失败<br />重新上传'
},
vanSkuStepper: {
quotaLimit: (quota: number) => `限购${quota}`,
quotaStart: (start: number) => `${start}件起售`,
comma: '',
num: '购买数量'
},
vanSkuMessages: {