ElementUI开发商品规格组件

电商后台需求-商品规格组件,参数是我们业务上需要的,不过八九不离十,使用elementUI库写的该组件,组件中的上传图片使用了oss-upload组件(详见另一文:阿里oss上传组件

 

<template>
  <div class="sku-list">
    <template v-if="!disabled">
      <div class="sku-list-head">
        <el-button type="primary" size="mini" @click="addSkuRow"
          >添加规格</el-button
        >
      </div>
      <div
        class="sku-list-item"
        v-for="(item, index) in skuData.attrList"
        :key="index"
      >
        <div class="sku-list-item-main">
          <div class="sku-list-item__layout">
            <span class="span">规格名</span>
            <el-input
              size="small"
              v-model="item.attrName"
              class="input"
            ></el-input>
          </div>
          <div class="sku-list-item__layout">
            <span class="span">规格值</span>
            <div class="sku-list-item-tags">
              <el-tag
                class="sku-list-item-tag"
                closable
                @close="removeSkuAttr(index)"
                v-for="(subitem, i) in item.attrValue"
                :key="i"
                >{{ subitem.attrValue }}</el-tag
              >
              <el-button
                size="small"
                icon="el-icon-plus"
                @click="addSkuAttr(index)"
                >添加</el-button
              >
            </div>
          </div>
        </div>
        <el-button
          type="text"
          size="small"
          class="sku-list-item-removeBtn"
          @click="removeSkuRow(index)"
          >删除规格</el-button
        >
      </div>
    </template>
    <el-table border :data="skuData.skuList">
      <el-table-column label="图片" align="center" width="120">
        <template slot-scope="scope">
          <oss-upload
            :disabled="disabled"
            :on-success="
              (res, file) => onUploadImgSuccess(res, file, scope.row)
            "
            dir="erp/goods"
          >
            <img
              v-if="scope.row.icon"
              :src="scope.row.icon"
              class="goods-img"
            />
            <el-button v-else-if="!disabled" type="text" size="small"
              >上传图片</el-button
            >
          </oss-upload>
        </template>
      </el-table-column>
      <el-table-column
        label="规格"
        align="center"
        prop="attrPath"
      ></el-table-column>
      <el-table-column label="供货价格" align="center">
        <template slot-scope="scope">
          <el-input
            :readonly="disabled"
            v-model="scope.row.priceCost"
          ></el-input>
        </template>
      </el-table-column>
      <el-table-column label="销售价格" align="center">
        <template slot-scope="scope">
          <el-input
            :readonly="disabled"
            v-model="scope.row.priceCash"
          ></el-input>
        </template>
      </el-table-column>
      <el-table-column label="划线价格" align="center">
        <template slot-scope="scope">
          <el-input
            :readonly="disabled"
            v-model="scope.row.priceOriginal"
          ></el-input>
        </template>
      </el-table-column>
      <el-table-column label="商品库存" align="center">
        <template slot-scope="scope">
          <el-input :readonly="disabled" v-model="scope.row.stock"></el-input>
        </template>
      </el-table-column>
      <!-- <el-table-column label="商品预警值" align="center">
        <template slot-scope="scope">
          <el-input :readonly="disabled" v-model="scope.row.stock"></el-input>
        </template>
      </el-table-column> -->
      <!-- <el-table-column v-if="!disabled" label="操作" align="center">
        <template>
          <el-button type="text" size="small">删除</el-button>
          <el-button type="text" size="small">上移</el-button>
        </template>
      </el-table-column> -->
    </el-table>
  </div>
</template>

<script>
export default {
  model: {
    prop: "skuData",
    event: "change",
  },
  props: {
    skuData: {
      type: Object,
      default: () => ({}),
    },
    disabled: {
      type: Boolean,
      default: false,
    },
  },
  data() {
    return {};
  },
  watch: {
    "skuData.attrList": {
      handler() {
        if (!this.disabled) {
          this.$set(this.skuData, "skuList", this.getTable());
        }
      },
      deep: true,
      immediate: true,
    },
  },
  methods: {
    // 添加规格行
    addSkuRow(i) {
      this.skuData.attrList.push({
        attrName: "",
        attrValue: [],
      });
      this.$emit("change", this.skuData);
    },

    // 删除规格行
    removeSkuRow(i) {
      this.skuData.attrList.splice(i, 1);
      this.$emit("change", this.skuData);
    },
    // 删除规格属性值
    removeSkuAttr(a, b) {
      this.skuData.attrList[a].attrValue.splice(b, 1);
      this.$emit("change", this.skuData);
    },
    // 添加规格属性值
    addSkuAttr(i) {
      this.$prompt("请输入规格值", "添加规格值", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        inputPattern: /\S+/,
        inputErrorMessage: "规格值不能为空",
        closeOnClickModal: false,
      }).then(({ value }) => {
        this.skuData.attrList[i].attrValue.push({
          attrValue: value,
        });
        this.$emit("change", this.skuData);
      });
    },
    onUploadImgSuccess(res, file, row) {
      if (!file) {
        return;
      }
      row.icon = file;
      this.$emit("change", this.skuData);
    },
    getTable() {
      const table = [];
      const attrValueAry = [];
      const arr = [];
      const tmpSkuData = (this.skuData.attrList || []).filter(
        (d) => d.attrName != "" && d.attrValue.length > 0
      );
      if (!tmpSkuData || tmpSkuData.length == 0) {
        return [];
      }

      tmpSkuData.forEach((item) => {
        attrValueAry.push(item.attrValue);
      });

      function func(skuarr = [], i) {
        for (let j = 0; j < attrValueAry[i].length; j++) {
          if (i < attrValueAry.length - 1) {
            skuarr[i] = attrValueAry[i][j];
            func(skuarr, i + 1);
          } else {
            arr.push([...skuarr, attrValueAry[i][j]]);
          }
        }
      }
      func([], 0);
      arr.forEach((item) => {
        let attrPath = "",
          findItem,
          tableItem;
        item.forEach((d, idx) => {
          attrPath += `${tmpSkuData[idx].attrName}:${d.attrValue};`;
        });
        findItem =
          this.skuData.initSkulist.find((item) => {
            return attrPath.includes(item.attrPath);
          }) || {};

        tableItem = Object.assign(
          {
            priceCost: 0,
            priceCash: 0,
            priceOriginal: 0,
            stock: 0,
            icon: null,
          },
          findItem,
          {
            attrPath,
          }
        );
        table.push(tableItem);
      });
      return table;
    },
  },
};
</script>

<style lang="scss" scoped>
.sku-list {
  &-head {
    margin-bottom: 10px;
  }
  &-item {
    display: flex;
    align-items: center;
    border: 1px solid #eee;
    border-radius: 5px;
    margin-bottom: 20px;
    padding: 20px 50px;

    &-main {
      flex: 1;
    }
    &-removeBtn {
      margin-left: 20px;
      color: #f56c6c;
    }
    &__layout {
      display: flex;
      align-items: center;
      margin-bottom: 20px;
      &:last-child {
        margin-bottom: 0;
      }
      .input {
        width: 240px;
      }
      .span {
        font-size: 13px;
        font-weight: bold;
        margin-right: 10px;
      }
    }
    &-tags {
      flex: 1;
    }
    &-tag {
      margin-bottom: 10px;
      margin-right: 10px;
    }
  }
}
</style>

 

posted @ 2022-05-13 14:36  豆浆不要油条  阅读(778)  评论(0编辑  收藏  举报