Vue实现SKU的界面选择

预览

gif展示

DEMO和使用方法

DEMO:https://guosugaz.gitee.io/kun-vue-sku/
github: https://github.com/Guosugaz/kun-vue-sku
码云:https://gitee.com/guosugaz/kun-vue-sku

实现思路

说明使用的数据

const info = [
    {
        id: 1,price: 99,store: 9, 颜色:"粉色,https://inews.gtimg.com/newsapp_ls/0/12169344339_295195/0",尺码: "小",内存: "4g",
    },
    {
        id: 2,price: 99,store: 9,颜色: "粉色",尺码: "小",内存: "8g",
    },
    {
        id: 3,price: 33,store: 99,颜色: "粉色",尺码: "大",内存: "4g",
    },
    {
        id: 4,price: 99,store: 9,颜色: "黄色",尺码: "小",内存: "4g",
    },
    {
        id: 5,price: 14,store: 99,颜色: "蓝色",尺码: "大",内存: "8g",
    }
]
const showInfo = {
    "颜色": [
        { "disable": false, "active": false, "value": "粉色", "img": "https://inews.gtimg.com/newsapp_ls/0/12169344339_295195/0" },
        { "disable": false, "active": false, "value": "黄色" },
        { "disable": false, "active": false, "value": "蓝色" }
    ],
    "尺码": [
        { "disable": false, "active": false, "value": "小" },
        { "disable": false, "active": false, "value": "大" }
    ],
    "内存": [
        { "disable": false, "active": false, "value": "4g" },
        { "disable": false, "active": false, "value": "8g" }
    ]
}
const showInfoKeys = Object.keys(showInfo);
const select = {}; // {颜色: '粉色'}
const selectKeys = []; // 已选择的规格
1.首先获取各个sku和未完全选择的库存
// 未完全选择的sku库存
let skuPartNameStock = {};
// 完全的sku库存
let skuStock = {};

// 处理后端数据为展示数据时拼接完整的sku库存和id
function getInfo() {
	// 处理数据 实现详情github库 /src/lib/Spec.vue getInfo函数
	....
	// 插入完成的sku 库存和id
    skuStock[valueArr.join("-")] = `${item[storeKey]},${item.id}`;
}

/* 
* 核心算法,获取已选择sku的库存数
* @param {Array} selected 已选择的sku数组 ["粉丝", "L"]
*/ 
function getRemainByKey(selected = []) {
    const selectedJoin = selected.join("-");
   // 如果已有缓存则返回
    if (typeof skuPartNameStock[selectedJoin] !== "undefined") {
        return skuPartNameStock[selectedJoin];
    }
    // 所有sku已选择 及时缓存
    if (selected.length === showInfoKeys.length) {
        skuPartNameStock[selectedJoin] = skuStock[selectedJoin]
            ? Number(skuStock[selectedJoin].split(",")[0])
            : 0;
        return skuPartNameStock[selectedJoin];
    }

    let remainStock = 0;
    const willSelected = [];

    for (let i = 0; i < showInfoKeys.length; i += 1) {
        let thatArr = showInfo[showInfoKeys[i]];
        // 对应规格的sku是否已选择
        const exist = thatArr.find(
            ({ value }) => value === selected[0]
        );
        if (exist && selected.length > 0) {
            willSelected.push(selected.shift());
        } else {
            // 对应sku未选择,则遍历该规格所有sku
            for (let j = 0; j < thatArr.length; j += 1) {
                remainStock += getRemainByKey(
                    willSelected.concat(thatArr[j].value, selected)
                );
            }
            break;
        }
    }
    // 返回前缓存
    skuPartNameStock[selectedJoin] = remainStock;
    return skuPartNameStock[selectedJoin];
}

处理后的数据

// skuPartNameStock
{
	"粉色-小-4g":9,
	"粉色-小-8g":9,
	"粉色-小":18,
	"粉色-大-4g":99,
	"粉色-大-8g":0,
	"粉色-大":99,
	"粉色":117,
	"黄色-小-4g":9,
	"黄色-小-8g":0,
	"黄色-小":9,
	"黄色-大-4g":0,
	"黄色-大-8g":0,
	"黄色-大":0,
	"黄色":9,
	"蓝色-小-4g":0,
	"蓝色-小-8g":0,
	"蓝色-小":0,
	"蓝色-大-4g":0,
	"蓝色-大-8g":99,
	"蓝色-大":99,
	"蓝色":99,"":225,
	"粉色-4g":108,
	"粉色-8g":9
}
// skuStock
{
	"粉色-小-4g":"9,1",
	"粉色-小-8g":"9,2",
	"粉色-大-4g":"99,3",
	"黄色-小-4g":"9,4",
	"蓝色-大-8g":"99,5"
}
2.更新状态
// 获取 selectKeys
fucntion  getSelectKeys() {
    let arr = [];
    showInfoKeys.forEach((key, index) => {
        arr[index] = select[key] ? select[key] : "";
    });
    selectKeys = arr;
}

// 更新状态
fucntion fetchStatus() {
   // 根据已选择的sku来筛选库存
   	showInfoKeys.forEach((key, skuIdx) => {
    let sku = showInfo[key];
    const curSelected = selectKeys.slice();

    // 已选的不用更新
    sku.forEach((skuInfo) => {
	        // 已选择规格的跳过
	        if (skuInfo.active) return;
	
	        // 将不同sku代入计算库存
	        const cacheKey = curSelected[skuIdx];
	        // 组合没选中的值和已选中的值
	        curSelected[skuIdx] = skuInfo.value;
	        // 获取不同组合的库存
	        const stock = getRemainByKey(
	            curSelected.filter((item) => item)
	        );
	        curSelected[skuIdx] = cacheKey;
	
	        // 更新sku状态
	        skuInfo.disable = stock <= 0;
	    });
 	});
}

参考

https://www.cnblogs.com/formercoding/p/12995715.html
https://quincychen.cn/sku_algorithm/

后记

推荐自己根据项目的需求改写该组件,组件存放位置 /src/lib/Spec.vue

  • 3
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值