SKU
SKU介绍
最小存货单位(SKU),全称为Stock Keeping Unit,即库存进出计量的基本单元。SKU引申为产品统一编号的简称,每种产品均对应有唯一的SKU号。对一种商品
而言,当其品牌、型号、配置、等级、花色、包装容量、单位、生产日期、保质期、用途、价格、产地等属性中任一属性与其他商品存在不同时,都拥有自己唯一的SKU号。
SKU本身多用于电商领域,,对于前端工程师而言,更多关注 SKU算法。
为什么需要SKU算法,比如如何根据手上的数据 来实现 这个 功能
数据
功能
实现以上效果的关键 便是 SKU算法
在当前项目中,我们使用的是uniapp 插件市场提供的 插件,该插件内置了SKU算法,我们只需要按照数据固定格式传递给它,便能实途中效果。
SKU插件的基本使用
步骤
- uniapp官网-插件-跳转插件市场,搜索sku
- 下载实例项目zip
- 解压打开路径:uni_modules\vk-data-goods-sku-popup\components
- 复制里面的两个组件即可
关键属性
属性名 | 含义 |
---|---|
v-model | 用来控制 组件显示和隐藏 |
mode | 1:都显示 2:只显示购物车 3:只显示立即购买 |
localdata | 商品信息本地数据源 |
ref | 组件实例 |
@add-cart | 加入购物车事件 |
@buy-now | 立即购买事件 |
步骤:
localdata
js
{
"_id":"002",
"name": "迪奥香水",
"goods_thumb":"https://res.lancome.com.cn/resources/2020/9/11/15998112890781924_920X920.jpg?version=20200917220352530",
"sku_list": [
{
"_id": "004",
"goods_id": "002",
"goods_name": "迪奥香水",
"image": "https://res.lancome.com.cn/resources/2020/9/11/15998112890781924_920X920.jpg?version=20200917220352530",
"price": 19800,
"sku_name_arr": ["50ml/瓶"],
"stock": 100
},
{
"_id": "005",
"goods_id": "002",
"goods_name": "迪奥香水",
"image": "https://res.lancome.com.cn/resources/2020/9/11/15998112890781924_920X920.jpg?version=20200917220352530",
"price": 9800,
"sku_name_arr": ["70ml/瓶"],
"stock": 100
}
],
"spec_list": [
{
"list": [
{
"name": "20ml/瓶"
},
{
"name": "50ml/瓶"
},
{
"name": "70ml/瓶"
}
],
"name": "规格"
}
]
}
页面代码
vue
<!-- SKU -->
<vk-data-goods-sku-popup
v-model="isShowSku"
:mode="skuMode"
:localdata="goodsSku"
ref="skuRef"
@add-cart="onAddCart"
@buy-now="onBuyNow"
:amount-type="0"
/>
数据格式转换参考
js
// sku_list,有库存的商品,所以用户可以选择
// spec_list 所有的规格 列表
this.goodsSku = {
// 商品id
_id: this.goods.id,
// 商品名称
name: this.goods.name,
// 商品主图
goods_thumb: this.goods.mainPictures[0],
// sku_list,有库存的商品,所以用户可以选择
sku_list: this.goods.skus.map((v) => ({
// 商品的skuId
_id: v.id,
// 商品的id
goods_id: this.goods.id,
// 商品名称
goods_name: this.goods.name,
// 商品主图
image: this.goods.mainPictures[0],
// sku对应的价格
price: v.price,
// sku对应的规格名称
sku_name_arr: v.specs.map((vv) => vv.valueName),
stock: v.inventory,
})),
// spec_list 所有的规格 列表
spec_list: this.goods.specs.map((v) => ({
// list代表是规格的集合,数据结构为
// "list": [{"name": "红色"},{"name": "黑色"},{"name": "白色"}]
list: v.values.map((vv) => ({
name: vv.name,
})),
// name 代表显示的规格名称
name: v.name,
})),
};
},
打开加入购物车、打开立即购买
src\pages\goods\index.vue
diff
<!-- 用户操作 -->
<view class="toolbar">
<view class="icons">
<button class="collect"><text class="icon-heart"></text>收藏</button>
<button class="contact" open-type="contact">
<text class="icon-handset"></text>客服
</button>
<button class="cart" >
<text class="icon-cart"></text>购物车
</button>
</view>
<view class="buttons">
<view
data-button-type="cart"
class="addcart"
+ @click="showSku(2)"
>
加入购物车
</view>
<view
data-button-type="payment"
class="payment"
+ @click="showSku(3)"
>
立即购买
</view>
</view>
</view>
js
methods: {
showSku(mode) {
this.skuMode = mode;
this.isShowSku = true;
},
}
加入购物车
目标:实现加入购物车功能
步骤:
1、封装API
src/api/cart.js
js
import http from "@/utils/http";
/**
* 加入购物车
*/
export const addCartAPI = (skuId, count) => {
return http({
url: "/member/cart",
method: "post",
data: { skuId, count },
});
};
2、声明数据selectedGood
js
data() {
return {
// ... 省略其它代码
selectedGood: "",
};
},
3、监听add-cart事件、调用API
4、修改选中商品规格、插值显示
5、提示用户、关闭弹出层
js
async onAddCard(selectShop) {
// 3. 监听add-cart事件、调用API
const { result } = await addCartAPI(selectShop._id, selectShop.buy_num);
// 4、修改选中商品规格、插值显示
this.selectGood = result.attrsText;
// 5. 提示用户, 关闭弹出层
this.isShowSku = false;
uni.showToast({
title: "添加成功",
icon: "success",
});
},
优化-显示选中的规格
目标:关闭Sku,显示选中的规格
步骤:
2、加入购物车后、修改selectedGood
3、关闭Sku时,显示选中的规格
代码:
1、绑定ref
2、监听关闭事件
diff
<vk-data-goods-sku-popup
v-model="isShowSku"
:mode="skuMode"
:localdata="list"
+ ref="sku-popup"
+ @close="onCloseSku"
:amount-type="0"
@add-cart="onAddCard"
/>
3、通过ref获取组件实例
js
async onCloseSku() {
this.selectedGood = this.$refs.skuRef.selectArr.join(" ").trim();
},
跳转到购物车
1、绑定点击事件
diff
<view class="toolbar">
<view class="icons">
<button class="collect"><text class="icon-heart"></text>收藏</button>
<button class="contact" open-type="contact">
<text class="icon-handset"></text>客服
</button>
<button class="cart"
+ @click="onGoCart"
>
<text class="icon-cart"></text>购物车
</button>
</view>
<view class="buttons">
... 省略...
</view>
</view>
2、跳转到购物车
js
onGoCart() {
uni.switchTab({ url: "/pages/cart/index" });
},