Let’s record the SKU implementation in case it’s useful and forgotten later
First, we break down the SKU into four steps
- Add a specification value
- Generate table header
- Generate table data
- Merged cell
I’m using firefly mall’s implementation here
-
Add a specification value
// This id is generated by the front desk, but I always feel there is something wrong with it. // Add specification values are similar function addSpecs() { if(! specsFormData.specsName)return message.warning('Specification name cannot be empty! '); if(! specsFormData.specsValue)return message.warning('Specification value cannot be empty! '); formData.specsTree.push({ ... specsFormData,specsValue: ' '.specsValues: [{specsValName: specsFormData.specsValue, specsValId: buildUUID(), }, ], specsId: buildUUID(), }); specsTreeForm.value.resetFields(); tableRender(); } Copy the code
-
Generate table header
// 1. We listen for specification changes and extract the specification into the format ant-Desgin wants // 2. TableColumns is the result of the final merge 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',})); });Copy the code
-
Generate table data
// This step is tricky // A little hard to explain // I just want to be // The first step is to organize all values into a hierarchy // Generate Descartes what is the definition of Descartes is to generate hierarchical data and know what it does // skuKey is the key to the combination of these three values function tableRender() { // Collate all specification groups const specsGroupArr = buildSpecsGroup(); // Generate a Cartesian data set const cartesianList = cartesianProductOf(specsGroupArr); // TODO merges cells // Generate the SKU field name buildSkuColumns(); // Generate SKU list data 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) { // Generate a new skuList const newSkuList = []; const specsList = formData.specsTree; for (let i = 0; i < cartesianList.length; i++) { constnewSkuItem = { ... defaultSKU,key: i, // skuKey is used to merge old records skuKey: cartesianList[i].map((item) = > item.specsValId).join('_'), // skuKeys is used to pass parameters to the back end 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(newSkuItemas never); } // Old SKU data is compatible return oldSkuList(newSkuList); } // Merge existing SKU data function oldSkuList(newSkuList) { const oldSkuList = formData.tableTree.concat(); if(! oldSkuList.length || ! newSkuList.length) {return newSkuList; } for (const index in newSkuList) { // Find old records that match let oldSkuItem = {}; if (oldSkuList.length === newSkuList.length) { oldSkuItem = cloneDeep(oldSkuList[index]); } else { oldSkuItem = oldSkuList.find((item) = > { return item.skuKey === newSkuList[index].skuKey; }); } // Write a new recordnewSkuList[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])); }); }); returnret; }, [[]]); };Copy the code
And that’s about it. Merge cells and just parse them according to skukey
I’ll write it then