mirror of
https://gitee.com/vant-contrib/vant.git
synced 2025-04-06 03:57:59 +08:00
[new feature] sku组件增加步进器相关自定义配置 (#600)
This commit is contained in:
parent
1b85c09a75
commit
4270354a67
@ -20,6 +20,24 @@
|
||||
</div>
|
||||
</demo-block>
|
||||
|
||||
<demo-block :title="$t('title2')">
|
||||
<div class="sku-container">
|
||||
<van-sku
|
||||
v-model="showBase"
|
||||
:sku="$t('sku').sku"
|
||||
:goods="$t('sku').goods_info"
|
||||
:goods-id="$t('sku').goods_id"
|
||||
:hide-stock="$t('sku').sku.hide_stock"
|
||||
:quota="$t('sku').quota"
|
||||
:quota-used="$t('sku').quota_used"
|
||||
:custom-stepper-config="customStepperConfig"
|
||||
@buy-clicked="onBuyClicked"
|
||||
@add-cart="onAddCartClicked"
|
||||
/>
|
||||
<van-button type="primary" @click="showBase = true" block>{{ $t('title2') }}</van-button>
|
||||
</div>
|
||||
</demo-block>
|
||||
|
||||
<demo-block :title="$t('advancedUsage')">
|
||||
<div class="sku-container">
|
||||
<van-sku
|
||||
@ -52,17 +70,20 @@
|
||||
|
||||
<script>
|
||||
import data from '../mock/sku';
|
||||
import { LIMIT_TYPE } from '../../../packages/sku/constants';
|
||||
|
||||
export default {
|
||||
i18n: {
|
||||
'zh-CN': {
|
||||
sku: data['zh-CN'],
|
||||
title2: '自定义步进器相关配置',
|
||||
stepperTitle: '我要买',
|
||||
button1: '积分兑换',
|
||||
button2: '买买买'
|
||||
},
|
||||
'en-US': {
|
||||
sku: data['en-US'],
|
||||
title2: 'Custom Stepper Related Config',
|
||||
stepperTitle: 'Stepper title',
|
||||
button1: 'Button',
|
||||
button2: 'Button'
|
||||
@ -76,6 +97,22 @@ export default {
|
||||
initialSku: {
|
||||
s1: '30349',
|
||||
s2: '1193'
|
||||
},
|
||||
customStepperConfig: {
|
||||
quotaText: '单次限购100件',
|
||||
handleOverLimit: (data) => {
|
||||
const { action, limitType, quota } = data;
|
||||
|
||||
if (action === 'minus') {
|
||||
Toast('至少选择一件商品');
|
||||
} else if (action === 'plus') {
|
||||
if (limitType === LIMIT_TYPE.QUOTA_LIMIT) {
|
||||
Toast(`限购${quota}件`);
|
||||
} else {
|
||||
Toast('库存不够了~~');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
},
|
||||
|
@ -27,6 +27,23 @@ Vue.use(Sku);
|
||||
/>
|
||||
```
|
||||
|
||||
#### Custom Stepper Config
|
||||
|
||||
```html
|
||||
<van-sku
|
||||
v-model="showBase"
|
||||
:sku="sku"
|
||||
:goods="goods"
|
||||
:goods-id="goodsId"
|
||||
:hide-stock="sku.hide_stock"
|
||||
:quota="quota"
|
||||
:quota-used="quotaUsed"
|
||||
:custom-stepper-config="customStepperConfig"
|
||||
@buy-clicked="onBuyClicked"
|
||||
@add-cart="onAddCartClicked"
|
||||
/>
|
||||
```
|
||||
|
||||
#### Advanced Usage
|
||||
|
||||
```html
|
||||
@ -72,6 +89,7 @@ Vue.use(Sku);
|
||||
| reset-selected-sku-on-hide | Whether to reset selected sku when hide | `Boolean` | `false` | - |
|
||||
| disable-stepper-input | Whether to disable stepper input | `Boolean` | `false` | - |
|
||||
| stepper-title | Quantity title | `String` | `Quantity` | - |
|
||||
| custom-stepper-config | Custom stepper related config | `Object` | `{}` | - |
|
||||
|
||||
### Event
|
||||
|
||||
@ -156,6 +174,32 @@ goods: {
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
#### customStepperConfig Data Structure
|
||||
```javascript
|
||||
customStepperConfig: {
|
||||
// custom quota text
|
||||
quotaText: 'only 5 can buy',
|
||||
// custom callback when over limit
|
||||
handleOverLimit: (data) => {
|
||||
const { action, limitType, quota, quotaUsed } = data;
|
||||
|
||||
if (action === 'minus') {
|
||||
Toast('at least select one');
|
||||
} else if (action === 'plus') {
|
||||
// const { LIMIT_TYPE } = Sku.skuConstants;
|
||||
if (limitType === LIMIT_TYPE.QUOTA_LIMIT) {
|
||||
let msg = `Buy up to ${quota}`;
|
||||
if (quotaUsed > 0) msg += `,you already buy ${quotaUsed}`;
|
||||
Toast(msg);
|
||||
} else {
|
||||
Toast('not enough stock');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Event Params Data Structure
|
||||
|
||||
```javascript
|
||||
|
@ -27,6 +27,23 @@ Vue.use(Sku);
|
||||
/>
|
||||
```
|
||||
|
||||
#### 自定义步进器相关配置
|
||||
|
||||
```html
|
||||
<van-sku
|
||||
v-model="showBase"
|
||||
:sku="sku"
|
||||
:goods="goods"
|
||||
:goods-id="goodsId"
|
||||
:hide-stock="sku.hide_stock"
|
||||
:quota="quota"
|
||||
:quota-used="quotaUsed"
|
||||
:custom-stepper-config="customStepperConfig"
|
||||
@buy-clicked="onBuyClicked"
|
||||
@add-cart="onAddCartClicked"
|
||||
/>
|
||||
```
|
||||
|
||||
#### 高级用法
|
||||
|
||||
```html
|
||||
@ -73,6 +90,7 @@ Vue.use(Sku);
|
||||
| reset-selected-sku-on-hide | 窗口隐藏时重置已选择的sku | `Boolean` | `false` | - |
|
||||
| disable-stepper-input | 是否禁用sku中stepper的input框 | `Boolean` | `false` | - |
|
||||
| stepper-title | 数量选择组件左侧文案 | `String` | `购买数量` | - |
|
||||
| custom-stepper-config | 步进器相关自定义配置 | `Object` | `{}` | - |
|
||||
|
||||
### Event
|
||||
|
||||
@ -163,6 +181,31 @@ goods: {
|
||||
}
|
||||
```
|
||||
|
||||
#### customStepperConfig 对象结构
|
||||
```javascript
|
||||
customStepperConfig: {
|
||||
// 自定义限购文案
|
||||
quotaText: '每次限购xxx件',
|
||||
// 自定义步进器超过限制时的回调
|
||||
handleOverLimit: (data) => {
|
||||
const { action, limitType, quota, quotaUsed } = data;
|
||||
|
||||
if (action === 'minus') {
|
||||
Toast('至少选择一件商品');
|
||||
} else if (action === 'plus') {
|
||||
// const { LIMIT_TYPE } = Sku.skuConstants;
|
||||
if (limitType === LIMIT_TYPE.QUOTA_LIMIT) {
|
||||
let msg = `单次限购${quota}件`;
|
||||
if (quotaUsed > 0) msg += `,您已购买${quotaUsed}`;
|
||||
Toast(msg);
|
||||
} else {
|
||||
Toast('库存不够了~~');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 添加购物车和点击购买回调函数接收的 skuData 对象结构
|
||||
```javascript
|
||||
skuData: {
|
||||
|
@ -66,6 +66,7 @@
|
||||
:quota-used="quotaUsed"
|
||||
:disable-stepper-input="disableStepperInput"
|
||||
:hide-stock="hideStock"
|
||||
:custom-stepper-config="customStepperConfig"
|
||||
/>
|
||||
</slot>
|
||||
<!-- sku-messages -->
|
||||
@ -159,6 +160,10 @@ export default create({
|
||||
messagePlaceholderMap: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
},
|
||||
customStepperConfig: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
}
|
||||
},
|
||||
|
||||
@ -328,7 +333,15 @@ export default create({
|
||||
this.selectedNum = num;
|
||||
},
|
||||
|
||||
onOverLimit({ action, limitType, quota, quotaUsed }) {
|
||||
onOverLimit(data) {
|
||||
const { action, limitType, quota, quotaUsed } = data;
|
||||
const { handleOverLimit } = this.customStepperConfig;
|
||||
|
||||
if (handleOverLimit) {
|
||||
handleOverLimit(data);
|
||||
return;
|
||||
}
|
||||
|
||||
if (action === 'minus') {
|
||||
Toast(this.$t('least'));
|
||||
} else if (action === 'plus') {
|
||||
|
@ -12,7 +12,7 @@
|
||||
/>
|
||||
</div>
|
||||
<div v-if="!hideStock" class="van-sku__stock">{{ $t('remain', stock) }}</div>
|
||||
<div v-if="quota > 0" class="van-sku__quota">{{ $t('quota', quota) }}</div>
|
||||
<div v-if="quotaText" class="van-sku__quota">{{ quotaText }}</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -40,7 +40,8 @@ export default create({
|
||||
quota: Number,
|
||||
quotaUsed: Number,
|
||||
hideStock: Boolean,
|
||||
disableStepperInput: Boolean
|
||||
disableStepperInput: Boolean,
|
||||
customStepperConfig: Object
|
||||
},
|
||||
|
||||
data() {
|
||||
@ -69,6 +70,18 @@ export default create({
|
||||
}
|
||||
return this.skuStockNum;
|
||||
},
|
||||
quotaText() {
|
||||
const { quotaText } = this.customStepperConfig;
|
||||
let text = '';
|
||||
|
||||
if (quotaText) {
|
||||
text = quotaText;
|
||||
} else if (this.quota > 0) {
|
||||
text = this.$t('quota', this.quota);
|
||||
}
|
||||
|
||||
return text;
|
||||
},
|
||||
stepperLimit() {
|
||||
const quotaLimit = this.quota - this.quotaUsed;
|
||||
let limit;
|
||||
|
@ -2,3 +2,7 @@ export const LIMIT_TYPE = {
|
||||
QUOTA_LIMIT: 0,
|
||||
STOCK_LIMIT: 1
|
||||
};
|
||||
|
||||
export default {
|
||||
LIMIT_TYPE
|
||||
};
|
||||
|
@ -6,6 +6,7 @@ import SkuStepper from './components/SkuStepper';
|
||||
import SkuRow from './components/SkuRow';
|
||||
import SkuRowItem from './components/SkuRowItem';
|
||||
import skuHelper from './utils/skuHelper';
|
||||
import constants from './constants';
|
||||
|
||||
Sku.SkuActions = SkuActions;
|
||||
Sku.SkuHeader = SkuHeader;
|
||||
@ -14,5 +15,6 @@ Sku.SkuStepper = SkuStepper;
|
||||
Sku.SkuRow = SkuRow;
|
||||
Sku.SkuRowItem = SkuRowItem;
|
||||
Sku.skuHelper = skuHelper;
|
||||
Sku.skuConstants = constants;
|
||||
|
||||
export default Sku;
|
||||
|
@ -1,4 +1,5 @@
|
||||
import Sku from 'packages/sku';
|
||||
import Toast from 'packages/toast';
|
||||
import { mount } from 'avoriaz';
|
||||
import { DOMChecker } from '../utils';
|
||||
import data from '../mock/sku';
|
||||
@ -155,6 +156,60 @@ describe('Sku', (done) => {
|
||||
});
|
||||
});
|
||||
|
||||
it('should toast custom error when change step value', (done) => {
|
||||
wrapper = mount(Sku, {
|
||||
attachToDocument: true,
|
||||
propsData: {
|
||||
value: true,
|
||||
sku: data.sku,
|
||||
goodsId: data.goods_id,
|
||||
goods: goods,
|
||||
quota: data.quota,
|
||||
quotaUsed: data.quota_used,
|
||||
customStepperConfig: {
|
||||
quotaText: '单次限购100件',
|
||||
handleOverLimit: (data) => {
|
||||
const { action, limitType, quota } = data;
|
||||
|
||||
if (action === 'minus') {
|
||||
Toast('至少选择一件商品');
|
||||
} else if (action === 'plus') {
|
||||
if (limitType === 0) {
|
||||
Toast(`限购${quota}件`);
|
||||
} else {
|
||||
Toast('库存不够了~~');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// 点击减号
|
||||
const minusBtn = wrapper.find('.van-stepper__minus')[0];
|
||||
minusBtn.trigger('click');
|
||||
wrapper.vm.$nextTick(() => {
|
||||
const toastText = document.querySelector('.van-toast div');
|
||||
expect(toastText.textContent).to.equal('至少选择一件商品');
|
||||
|
||||
// 手动修改购买数量
|
||||
const stepperInput = wrapper.find('.van-stepper__input')[0];
|
||||
stepperInput.element.value = 20;
|
||||
stepperInput.trigger('input');
|
||||
wrapper.vm.$nextTick(() => {
|
||||
expect(+stepperInput.element.value).to.equal(data.quota - data.quota_used);
|
||||
|
||||
// 达到购买上限时,点击加号
|
||||
const plusBtn = wrapper.find('.van-stepper__plus')[0];
|
||||
plusBtn.trigger('click');
|
||||
wrapper.vm.$nextTick(() => {
|
||||
expect(toastText.textContent).to.equal(`限购${data.quota}件`);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should not render sku group when none_sku is true', (done) => {
|
||||
const newData = Object.assign({}, data);
|
||||
newData.sku.none_sku = true; // eslint-disable-line
|
||||
|
Loading…
x
Reference in New Issue
Block a user