SKU实现 记录一下吧 免得以后有用又忘记了
首先我们先将SKU解刨成4个步骤
- 添加规格 规格值
- 生成 table 头部
- 生成 table 数据
- 合并单元格
我这里借鉴了一下萤火商城的实现
-
添加规格 规格值
// 这里 id 是我前台生成的 但我总感觉哪里有问题(反正以后改,把 UUID 去掉即可) // 添加规格值也差不多 function addSpecs() { if (!specsFormData.specsName) return message.warning('规格名不能为空!'); if (!specsFormData.specsValue) return message.warning('规格值不能为空!'); formData.specsTree.push({ ...specsFormData, specsValue: '', specsValues: [ { specsValName: specsFormData.specsValue, specsValId: buildUUID(), }, ], specsId: buildUUID(), }); specsTreeForm.value.resetFields(); tableRender(); } -
生成 table 头部
// 1. 我们监听规格变化 将规格提取成 ant-desgin 想要的格式 // 2. tableColumns 是最终合并出的结果 const tableSpecsColTitle = ref([]); const tableColumns = computed(() => { return [...tableSpecsColTitle.value, ...columns]; }); watch(formData.specsTree, (arr) => { tableSpecsColTitle.value = arr.map((v, i) => ({ title: v.specsName, dataIndex: `skuProps.${i}.value.name`, width: '80px', })); }); -
生成 table 数据
// 这一步比较麻烦 // 有点难以讲解 // 反正就想当于 // 第一步 成组织 将所有values按层级提取出来 // 生成笛卡尔 这个笛卡尔怎么解释呢 反正就是生成层级数据 知道他干什么的就行了 // skuKey 这个字段很关键 就是这三个值的 id 联合 function tableRender() { // 整理所有的规格组 const specsGroupArr = buildSpecsGroup(); // 生成笛卡尔数据集合 const cartesianList = cartesianProductOf(specsGroupArr); // TODO 合并单元格 // 生成 SKU 字段名 buildSkuColumns(); // 生成 SKU 列表数据 const skuList = buildSkuList(cartesianList); formData.tableTree = skuList; } function buildSpecsGroup() { const specGroupArr = []; formData.specsTree.forEach((specGroup) => { const itemArr = []; specGroup.specsValues.forEach((value) => { itemArr.push(value as never); }); specGroupArr.push(itemArr as never); }); return specGroupArr; } function buildSkuColumns() {} function buildSkuList(cartesianList) { // 生成新的skuList const newSkuList = []; const specsList = formData.specsTree; for (let i = 0; i < cartesianList.length; i++) { const newSkuItem = { ...defaultSKU, key: i, // skuKey用于合并旧记录 skuKey: cartesianList[i].map((item) => item.specsValId).join('_'), // skuKeys用于传参给后端 skuProps: cartesianList[i].map((item, specsIndex) => { const specsItem = specsList[specsIndex]; return { group: { name: specsItem.specsName, id: specsItem.specsId, }, value: { name: item.specsValName, id: item.specsValId, }, }; }), }; newSkuList.push(newSkuItem as never); } // 兼容旧的sku数据 return oldSkuList(newSkuList); } // 合并已存在的sku数据 function oldSkuList(newSkuList) { const oldSkuList = formData.tableTree.concat(); if (!oldSkuList.length || !newSkuList.length) { return newSkuList; } for (const index in newSkuList) { // 查找符合的旧记录 let oldSkuItem = {}; if (oldSkuList.length === newSkuList.length) { oldSkuItem = cloneDeep(oldSkuList[index]); } else { oldSkuItem = oldSkuList.find((item) => { return item.skuKey === newSkuList[index].skuKey; }); } // 写入新纪录 newSkuList[index] = { ...newSkuList[index], ...pick(oldSkuItem, Object.keys(defaultSKU)), }; } return newSkuList; } /** * 生成笛卡尔积数据 * cartesianProductOf([arr1, arr2, arr3 ...]) */ const cartesianProductOf = (arrays) => { if (!arrays.length) { return []; } return Array.prototype.reduce.call( arrays, (arr1, arr2) => { var ret = []; arr1.forEach((v1) => { arr2.forEach((v2) => { ret.push(v1.concat([v2])); }); }); return ret; }, [[]], ); };
差不多就这些吧 合并单元格 也简单 根据 skukey 去解析就OK了
到时候在写吧