diff --git a/src/sku/README.md b/src/sku/README.md index c68b6e9fa..883683cb4 100644 --- a/src/sku/README.md +++ b/src/sku/README.md @@ -142,6 +142,7 @@ export default { | get-container | Return the mount node for sku | *string \| () => Element* | - | | safe-area-inset-bottom `v2.2.1` | Whether to enable bottom safe area adaptation | *boolean* | `false` | | start-sale-num `v2.3.0` | Minimum quantity | *number* | `1` | +| properties `2.4.0` | Goods properties | *array* | - | ### Events @@ -151,6 +152,7 @@ export default { | buy-clicked | Triggered when click buy button | data: object | | stepper-change | Triggered when stepper value changed | value: number | | sku-selected | Triggered when select sku | { skuValue, selectedSku, selectedSkuComb } | +| sku-prop-selected | Triggered when select property | { propValue, selectedProp, selectedSkuComb } | | open-preview | Triggered when open image preview | data: object | | close-preview | Triggered when close image preview | data: object | @@ -161,7 +163,7 @@ Use [ref](https://vuejs.org/v2/api/#ref) to get Sku instance and call instance m | Name | Description | Attribute | Return value | |------|------|------|------| | getSkuData | Get current skuData | - | skuData | -| resetSelectedSku | Reset selected sku to initial sku | - | - | 2.3.0 | +| resetSelectedSku `2.3.0` | Reset selected sku to initial sku | - | - | ### Slots @@ -226,10 +228,53 @@ sku: { placeholder: '' } ], - hide_stock: false + hide_stock: false, + properties: [ + { + k_id: 123, + k: 'More', + is_multiple: true, + v: [ + { + id: 1222, + name: 'Tea', + price: 1, + }, + { + id: 1223, + name: 'Water', + price: 1, + } + ], + } + ] } ``` +### properties Data Structure + +```javascript + [ + { + k_id: 123, + k: 'More', + is_multiple: true, + v: [ + { + id: 1222, + name: 'Tea', + price: 1, + }, + { + id: 1223, + name: 'Water', + price: 1, + } + ], + } + ] +``` + ### initialSku Data Structure ```javascript @@ -238,7 +283,10 @@ sku: { // Value:skuValueId s1: '30349', s2: '1193', - selectedNum: 3 + selectedNum: 3, + selectedProp: { + 123: [1222] + } } ``` @@ -324,7 +372,22 @@ skuData: { s1: '30349', s2: '1193', s3: '0', - stock_num: 111 + stock_num: 111, + properties: [ + { + k_id: 123, + k: 'More', + is_multiple: true, + v: [ + { + id: 1223, + name: 'Water', + price: 1 + } + ] + } + ], + property_price: 1 } } ``` diff --git a/src/sku/README.zh-CN.md b/src/sku/README.zh-CN.md index f74420181..006e33783 100644 --- a/src/sku/README.zh-CN.md +++ b/src/sku/README.zh-CN.md @@ -146,6 +146,7 @@ export default { | show-soldout-sku | 是否展示售罄的 sku,默认展示并置灰 | *boolean* | `true` | | safe-area-inset-bottom `v2.2.1` | 是否开启底部安全区适配,[详细说明](#/zh-CN/quickstart#di-bu-an-quan-qu-gua-pei) | *boolean* | `false` | | start-sale-num `v2.3.0` | 起售数量 | *number* | `1` | +| properties `2.4.0` | 商品属性 | *array* | - | ### Events @@ -155,6 +156,7 @@ export default { | buy-clicked | 点击购买回调 | skuData: object | | stepper-change | 购买数量变化时触发 | value: number | | sku-selected | 切换规格类目时触发 | { skuValue, selectedSku, selectedSkuComb } | +| sku-prop-selected | 切换商品属性时触发 | { propValue, selectedProp, selectedSkuComb } | | open-preview | 打开商品图片预览时触发 | data: object | | close-preview | 关闭商品图片预览时触发 | data: object | @@ -240,6 +242,30 @@ sku: { } ``` +### properties 对象结构 + +```javascript + [ // 商品属性 + { + k_id: 123, // 属性id + k: '加料', // 属性名 + is_multiple: true, // 是否可多选 + v: [ + { + id: 1222, // 属性值id + name: '珍珠', // 属性值名 + price: 1, // 属性值加价 + }, + { + id: 1223, + name: '椰果', + price: 1, + } + ], + } + ] +``` + ### initialSku 对象结构 ```javascript @@ -249,7 +275,13 @@ sku: { s1: '30349', s2: '1193', // 初始选中数量 - selectedNum: 3 + selectedNum: 3, + // 初始选中的商品属性 + // 键:属性id + // 值:属性值id列表 + selectedProp: { + 123: [1222] + } } ``` @@ -341,7 +373,22 @@ skuData: { s1: '30349', s2: '1193', s3: '0', - stock_num: 111 - } + stock_num: 111, + properties: [ + { + k_id: 123, + k: '加料', + is_multiple: true, + v: [ + { + id: 1223, + name: '椰果', + price: 1 + } + ] + } + ], + property_price: 1 + }, } ``` diff --git a/src/sku/Sku.js b/src/sku/Sku.js index 406f00094..3bf18ea75 100644 --- a/src/sku/Sku.js +++ b/src/sku/Sku.js @@ -11,7 +11,14 @@ import SkuStepper from './components/SkuStepper'; import SkuMessages from './components/SkuMessages'; import SkuActions from './components/SkuActions'; import { createNamespace, isDef } from '../utils'; -import { isAllSelected, isSkuChoosable, getSkuComb, getSelectedSkuValues, getSelectedPropValues } from './utils/skuHelper'; +import { + isAllSelected, + isSkuChoosable, + getSkuComb, + getSelectedSkuValues, + getSelectedPropValues, + getSelectedProperties, +} from './utils/skuHelper'; import { LIMIT_TYPE, UNSELECTED_SKU_VALUE_ID } from './constants'; const namespace = createNamespace('sku'); @@ -38,6 +45,7 @@ export default createComponent({ disableStepperInput: Boolean, safeAreaInsetBottom: Boolean, resetSelectedSkuOnHide: Boolean, + properties: Array, quota: { type: Number, default: 0 @@ -185,7 +193,7 @@ export default createComponent({ }; } if (skuComb) { - skuComb.properties = this.selectedPropValues; + skuComb.properties = getSelectedProperties(this.propList, this.selectedProp); skuComb.property_price = this.selectedPropValues.reduce((acc, cur) => acc + (cur.price || 0), 0); } } @@ -220,7 +228,7 @@ export default createComponent({ }, propList() { - return this.sku.properties || []; + return this.properties || []; }, imageList() { diff --git a/src/sku/demo/data.ts b/src/sku/demo/data.ts index e8447c84e..d04b25eeb 100644 --- a/src/sku/demo/data.ts +++ b/src/sku/demo/data.ts @@ -179,58 +179,58 @@ export const skuData = { required: 0 } ], - properties: [ - { - k_id: 123, - k: '加冰', - v: [ - { - id: 1222, - name: '少冰', - price: 1, - }, - { - id: 1223, - name: '去冰', - price: 1, - } - ], - }, - { - k_id: 133, - k: '不知道', - v: [ - { - id: 1244, - name: '什么', - price: 9, - } - ], - }, - { - k_id: 124, - k: '加料', - is_multiple: true, - v: [ - { - id: 1224, - name: '布丁', - price: 3, - }, - { - id: 1225, - name: '波霸', - price: 4, - }, - { - id: 1226, - name: '珍珠', - price: 5, - } - ], - } - ], }, + properties: [ + { + k_id: 123, + k: '加冰', + v: [ + { + id: 1222, + name: '少冰', + price: 1, + }, + { + id: 1223, + name: '去冰', + price: 1, + } + ], + }, + { + k_id: 133, + k: '打包', + v: [ + { + id: 1244, + name: '分开打包', + price: 9, + } + ], + }, + { + k_id: 124, + k: '加料', + is_multiple: true, + v: [ + { + id: 1224, + name: '布丁', + price: 3, + }, + { + id: 1225, + name: '波霸', + price: 4, + }, + { + id: 1226, + name: '珍珠', + price: 5, + } + ], + } + ], }; export const initialSku = { diff --git a/src/sku/demo/index.vue b/src/sku/demo/index.vue index e1e7d6a32..cb8f2436e 100644 --- a/src/sku/demo/index.vue +++ b/src/sku/demo/index.vue @@ -15,6 +15,7 @@ :close-on-click-overlay="closeOnClickOverlay" :message-config="messageConfig" :custom-sku-validator="customSkuValidator" + :properties="skuData.properties" disable-stepper-input reset-stepper-on-hide safe-area-inset-bottom @@ -46,6 +47,7 @@ :start-sale-num="skuData.start_sale_num" :custom-stepper-config="customStepperConfig" :message-config="messageConfig" + :properties="skuData.properties" hide-quota-text safe-area-inset-bottom @buy-clicked="onBuyClicked" @@ -76,6 +78,7 @@ :custom-stepper-config="customStepperConfig" :message-config="messageConfig" :show-soldout-sku="false" + :properties="skuData.properties" hide-quota-text safe-area-inset-bottom @buy-clicked="onBuyClicked" @@ -103,6 +106,7 @@ :quota="skuData.quota" :quota-used="skuData.quota_used" :start-sale-num="skuData.start_sale_num" + :properties="skuData.properties" show-add-cart-btn reset-stepper-on-hide safe-area-inset-bottom diff --git a/src/sku/utils/skuHelper.js b/src/sku/utils/skuHelper.js index 4dcbaca60..602800a18 100644 --- a/src/sku/utils/skuHelper.js +++ b/src/sku/utils/skuHelper.js @@ -120,12 +120,33 @@ export const getSelectedPropValues = (propList, selectedProp) => { const normalizeProp = normalizePropList(propList); return Object.keys(selectedProp).reduce((acc, cur) => { selectedProp[cur].forEach(it => { - acc.push(normalizeProp[cur][it]); + acc.push({ + ...normalizeProp[cur][it], + }); }); return acc; }, []); }; +export const getSelectedProperties = (propList, selectedProp) => { + const list = []; + (propList || []).forEach(prop => { + if (selectedProp[prop.k_id] && selectedProp[prop.k_id].length > 0) { + const v = []; + prop.v.forEach(it => { + if (selectedProp[prop.k_id].indexOf(it.id) > -1) { + v.push({ ...it }); + } + }); + list.push({ + ...prop, + v, + }); + } + }); + return list; +}; + export default { normalizeSkuTree, getSkuComb, @@ -133,4 +154,5 @@ export default { isAllSelected, isSkuChoosable, getSelectedPropValues, + getSelectedProperties, };