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('库存不够了~~');
+ }
+ }
+ }
}
};
},
diff --git a/docs/markdown/en-US/sku.md b/docs/markdown/en-US/sku.md
index bef63dc4d..3c35d5bf3 100644
--- a/docs/markdown/en-US/sku.md
+++ b/docs/markdown/en-US/sku.md
@@ -27,6 +27,23 @@ Vue.use(Sku);
/>
```
+#### Custom Stepper Config
+
+```html
+
+```
+
#### 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
diff --git a/docs/markdown/zh-CN/sku.md b/docs/markdown/zh-CN/sku.md
index d8e555ec4..21b4f3a19 100644
--- a/docs/markdown/zh-CN/sku.md
+++ b/docs/markdown/zh-CN/sku.md
@@ -27,6 +27,23 @@ Vue.use(Sku);
/>
```
+#### 自定义步进器相关配置
+
+```html
+
+```
+
#### 高级用法
```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: {
diff --git a/packages/sku/Sku.vue b/packages/sku/Sku.vue
index 475c86de3..7d503a2ab 100644
--- a/packages/sku/Sku.vue
+++ b/packages/sku/Sku.vue
@@ -66,6 +66,7 @@
:quota-used="quotaUsed"
:disable-stepper-input="disableStepperInput"
:hide-stock="hideStock"
+ :custom-stepper-config="customStepperConfig"
/>
@@ -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') {
diff --git a/packages/sku/components/SkuStepper.vue b/packages/sku/components/SkuStepper.vue
index 08f8f197b..4c705a41d 100644
--- a/packages/sku/components/SkuStepper.vue
+++ b/packages/sku/components/SkuStepper.vue
@@ -12,7 +12,7 @@
/>
{{ $t('remain', stock) }}
- {{ $t('quota', quota) }}
+ {{ quotaText }}
@@ -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;
diff --git a/packages/sku/constants.js b/packages/sku/constants.js
index 80b443ee6..0d83bd7ce 100644
--- a/packages/sku/constants.js
+++ b/packages/sku/constants.js
@@ -2,3 +2,7 @@ export const LIMIT_TYPE = {
QUOTA_LIMIT: 0,
STOCK_LIMIT: 1
};
+
+export default {
+ LIMIT_TYPE
+};
diff --git a/packages/sku/index.js b/packages/sku/index.js
index 4c21c126c..76ad3e005 100644
--- a/packages/sku/index.js
+++ b/packages/sku/index.js
@@ -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;
diff --git a/test/unit/specs/sku.spec.js b/test/unit/specs/sku.spec.js
index f78f6944f..499939444 100644
--- a/test/unit/specs/sku.spec.js
+++ b/test/unit/specs/sku.spec.js
@@ -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