基于element ui的sku生成组件,一键生成、批量设置

用element ui做一个商品sku生成组件,可以批量设置价格、库存、成本价,用import 引入组件并使用是实例给出效果如下。

image.png

组件代码:

<template>
  <div>
    <!-- 属性配置 -->
    <el-button @click="addAttribute">添加属性</el-button>
    <el-table :data="attributes" border style="width: 100%">
      <el-table-column prop="attributeName" label="属性名称"></el-table-column>
      <el-table-column label="属性值">
        <template v-slot="{ row }">
          <el-input v-model="row.attributeValues" placeholder="用竖线(|)分隔"></el-input>
        </template>
      </el-table-column>
      <el-table-column label="操作" width="100">
        <template v-slot="{ $index }">
          <el-button size="mini" type="danger" @click="removeAttribute($index)">删除</el-button>
        </template>
      </el-table-column>
    </el-table>

    <!-- 批量设置 -->
    <el-button @click="batchSetVisible = true">批量设置</el-button>
    <el-dialog title="批量设置" :visible.sync="batchSetVisible">
      <el-form :model="batchForm">
        <el-form-item label="价格" :label-width="formLabelWidth">
          <el-input v-model="batchForm.price"></el-input>
        </el-form-item>
        <el-form-item label="库存" :label-width="formLabelWidth">
          <el-input v-model.number="batchForm.store_count"></el-input>
        </el-form-item>
        <el-form-item label="成本价" :label-width="formLabelWidth">
          <el-input v-model.number="batchForm.cost_price"></el-input>
        </el-form-item>
        <el-form-item label="市场价" :label-width="formLabelWidth">
          <el-input v-model.number="batchForm.market_price"></el-input>
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="batchSetVisible = false">取消</el-button>
        <el-button type="primary" @click="applyBatchSet">确定</el-button>
      </span>
    </el-dialog>

    <!-- SKU列表 -->
    <el-button @click="generateSkus">生成SKU</el-button>
    <el-table :data="skus" border style="width: 100%" @cell-change="handleSkuChange">
      <el-table-column prop="spec_key" label="规格键名"></el-table-column>
      <el-table-column prop="spec_name" label="规格名称"></el-table-column>
      <el-table-column prop="store_count" label="库存">
        <template v-slot="{ row }">
          <el-input v-model.number="row.store_count" @input="handleSkuChange(row)"></el-input>
        </template>
      </el-table-column>
      <el-table-column prop="price" label="价格">
        <template v-slot="{ row }">
          <el-input v-model.number="row.price" @input="handleSkuChange(row)"></el-input>
        </template>
      </el-table-column>
      <el-table-column prop="cost_price" label="成本价">
        <template v-slot="{ row }">
          <el-input v-model.number="row.cost_price" @input="handleSkuChange(row)"></el-input>
        </template>
      </el-table-column>
      <el-table-column prop="market_price" label="市场价">
        <template v-slot="{ row }">
          <el-input v-model.number="row.market_price" @input="handleSkuChange(row)"></el-input>
        </template>
      </el-table-column>
      <el-table-column label="操作" width="100">
        <template v-slot="{ $index }">
          <el-button size="mini" type="danger" @click="removeSku($index)">删除</el-button>
        </template>
      </el-table-column>
    </el-table>
  </div>
</template>

<script>
export default {
  data() {
    return {
      attributes: [], // 存储属性及其值
      skus: [], // 存储生成的SKU列表
      batchSetVisible: false, // 控制批量设置对话框显示状态
      batchForm: {
        price: '',
        store_count: null,
        cost_price: null,
        market_price: null
      },
      formLabelWidth: '80px'
    };
  },
  watch: {
    skus: {
      deep: true,
      handler(newValue) {
        this.$emit('sku-updated', newValue);
      }
    }
  },
  methods: {
    addAttribute() {
      this.attributes.push({ attributeName: '', attributeValues: '' });
    },
    removeAttribute(index) {
      this.attributes.splice(index, 1);
    },
    generateSkus() {
      // 清空现有的SKU列表
      this.skus = [];

      // 获取所有属性值并创建所有可能的组合
      const combinations = this.createCombinations(this.attributes);

      // 根据组合生成SKUs
      combinations.forEach(combination => {
        const specKey = combination.join('_');
        const specName = combination.join('、');

        this.skus.push({
          spec_key: specKey,
          spec_name: specName,
          store_count: 0,
          price: 0.00,
          cost_price: 0.00,
          market_price: 0.00
        });
      });
    },
    createCombinations(attributes) {
      const valueLists = attributes.map(attr => attr.attributeValues.split('|').map(val => val.trim()));
      const result = [];
      function combine(tempArray, index) {
        if (index === valueLists.length) {
          result.push(tempArray.slice());
          return;
        }
        for (let i = 0; i < valueLists[index].length; i++) {
          tempArray[index] = valueLists[index][i];
          combine(tempArray, index + 1);
        }
      }
      combine([], 0);
      return result;
    },
    removeSku(index) {
      this.skus.splice(index, 1);
    },
    applyBatchSet() {
      const { price, store_count, cost_price, market_price } = this.batchForm;

      // 更新所有SKU对应的字段
      this.skus.forEach(sku => {
        if (price !== '') sku.price = parseFloat(price);
        if (store_count !== null) sku.store_count = store_count;
        if (cost_price !== null) sku.cost_price = cost_price;
        if (market_price !== null) sku.market_price = market_price;
      });

      // 关闭对话框
      this.batchSetVisible = false;
    },
    handleSkuChange(row) {
      // 触发更新事件,将最新的SKU数据传递给父组件
      this.$emit('sku-updated', this.skus);
    }
  }
};
</script>


调用实例:

import sku from '@/components/goods/sku.vue'

<sku @sku-updated="skuChange"></sku>

skuChange(sku){
  console.log(sku)
},


组合结果

[
    {
        "spec_key": "白色_大码",
        "spec_name": "白色、大码",
        "store_count": 2,
        "price": 1,
        "cost_price": 3,
        "market_price": 4
    },
    {
        "spec_key": "白色_中码",
        "spec_name": "白色、中码",
        "store_count": 2,
        "price": 1,
        "cost_price": 3,
        "market_price": 4
    },
    {
        "spec_key": "白色_小码",
        "spec_name": "白色、小码",
        "store_count": 2,
        "price": 1,
        "cost_price": 3,
        "market_price": 4
    },
    {
        "spec_key": "蓝色_大码",
        "spec_name": "蓝色、大码",
        "store_count": 2,
        "price": 1,
        "cost_price": 3,
        "market_price": 4
    },
    {
        "spec_key": "蓝色_中码",
        "spec_name": "蓝色、中码",
        "store_count": 2,
        "price": 1,
        "cost_price": 3,
        "market_price": 4
    },
    {
        "spec_key": "蓝色_小码",
        "spec_name": "蓝色、小码",
        "store_count": 2,
        "price": 1,
        "cost_price": 3,
        "market_price": 4
    }
]


稍微调整一下即可使用

评论/留言