Bootstrap

vue实现计算商品sku笛卡尔积(干货)

在 Vue 中计算商品 SKU 的笛卡尔积,您可以按照以下步骤进行:

  1. 定义商品属性和属性值

在 Vue 组件中定义商品属性和属性值,可以使用对象或数组来表示:

// 商品属性
const attributes = {
  color: {
    name: '颜色',
    values: [
      { name: '红色', value: 'red' },
      { name: '蓝色', value: 'blue' },
      { name: '绿色', value: 'green' },
    ],
  },
  size: {
    name: '尺寸',
    values: [
      { name: 'S', value: 's' },
      { name: 'M', value: 'm' },
      { name: 'L', value: 'l' },
    ],
  },
};
  1. 计算属性值组合

使用嵌套循环来计算商品属性值的笛卡尔积,生成所有可能的属性值组合。

const attributeValues = Object.values(attributes).map(attr => attr.values);

const cartesianProduct = (...arrays) => arrays.reduce((acc, curr) =>
  acc.flatMap(a => curr.map(c => [...a, c]))
, [[]]);

const attributeCombinations = cartesianProduct(...attributeValues);

返回数据结构如图

  1. 生成 SKU 列表

使用属性值组合来生成 SKU 列表,给每个 SKU 分配一个唯一的编号。

const skuList = attributeCombinations.map((attributes, index) => ({
  id: index + 1,
  attributes: attributes.reduce((acc, attr, index) => {
    acc[Object.keys(attributes)[index]] = attr;
    return acc;
  }, {}),
  price: 0,
  stock: 0,
}));

在生成 SKU 列表时,您可以根据需要为每个 SKU 分配初始价格和库存数量,或者在后续的处理中动态计算。

  1. 显示商品属性和 SKU 列表

在 Vue 组件中,您可以使用 v-for 指令来显示商品属性和 SKU 列表。

<!-- 显示商品属性 -->
<div v-for="(attribute, attributeName) in attributes" :key="attributeName">
  <div>{{ attribute.name }}</div>
  <div>
    <div v-for="value in attribute.values" :key="value.value">
      <input type="radio" :id="`${attributeName}_${value.value}`"
        :name="attributeName" :value="value.value"
        v-model="selectedAttributes[attributeName]">
      <label :for="`${attributeName}_${value.value}`">{{ value.name }}</label>
    </div>
  </div>
</div>

<!-- 显示 SKU 列表 -->
<table>
  <thead>
    <tr>
      <th>ID</th>
      <th v-for="attribute in Object.keys(attributes)">{{ attributes[attribute].name }}</th>
      <th>价格</th>
      <th>库存</th>
    </tr>
  </thead>
  <tbody>
    <tr v-for="sku in skuList" :key="sku.id">
      <td>{{ sku.id }}</td>
      <td v-for="attribute in Object.keys(attributes)">{{ sku.attributes[attribute] }}</td>
      <td>{{ sku.price }}</td>
      <td>{{ sku.stock }}</td>
    </tr>
  </tbody>
</table>
;