当前位置:首页 > VUE

vue实现sku选择

2026-02-20 06:04:11VUE

Vue 实现 SKU 选择

SKU(Stock Keeping Unit)选择是电商系统中常见的功能,允许用户通过组合不同属性(如颜色、尺寸)来选择商品。以下是基于 Vue 的实现方法。

数据结构设计

SKU 数据通常包含属性列表和 SKU 列表。属性列表描述商品的维度(如颜色、尺寸),SKU 列表包含具体组合及其库存、价格等信息。

data() {
  return {
    attributes: [
      { name: '颜色', values: ['红色', '蓝色', '绿色'] },
      { name: '尺寸', values: ['S', 'M', 'L'] }
    ],
    skus: [
      { id: 1, color: '红色', size: 'S', stock: 10, price: 100 },
      { id: 2, color: '红色', size: 'M', stock: 5, price: 120 },
      // 其他 SKU...
    ],
    selected: {} // 存储用户选择的属性值
  }
}

属性选择交互

为每个属性创建选择按钮,用户点击时更新 selected 对象。

<div v-for="attr in attributes" :key="attr.name">
  <h3>{{ attr.name }}</h3>
  <button 
    v-for="value in attr.values" 
    :key="value"
    @click="selectAttr(attr.name, value)"
    :class="{ active: selected[attr.name] === value }"
  >
    {{ value }}
  </button>
</div>
methods: {
  selectAttr(attrName, value) {
    this.$set(this.selected, attrName, value)
    this.checkAvailability()
  }
}

SKU 可用性检查

根据当前选择的属性组合,检查哪些 SKU 可用并更新 UI。

methods: {
  checkAvailability() {
    const selectedAttrs = Object.values(this.selected)
    if (selectedAttrs.length === this.attributes.length) {
      // 完整选择时查找匹配的 SKU
      const matchedSku = this.skus.find(sku => 
        this.attributes.every(attr => 
          sku[attr.name.toLowerCase()] === this.selected[attr.name]
        )
      )
      // 处理匹配结果...
    }
  }
}

禁用不可选选项

当某些属性组合无库存时,应禁用对应选项。

computed: {
  disabledValues() {
    const disabled = {}
    this.attributes.forEach(attr => {
      disabled[attr.name] = attr.values.filter(value => {
        const tempSelected = { ...this.selected, [attr.name]: value }
        return !this.hasStockForCombination(tempSelected)
      })
    })
    return disabled
  }
}

完整示例

<template>
  <div>
    <div v-for="attr in attributes" :key="attr.name">
      <h3>{{ attr.name }}</h3>
      <button 
        v-for="value in attr.values" 
        :key="value"
        @click="selectAttr(attr.name, value)"
        :class="{ 
          active: selected[attr.name] === value,
          disabled: disabledValues[attr.name]?.includes(value)
        }"
        :disabled="disabledValues[attr.name]?.includes(value)"
      >
        {{ value }}
      </button>
    </div>

    <div v-if="currentSku">
      <p>价格: {{ currentSku.price }}</p>
      <p>库存: {{ currentSku.stock }}</p>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      attributes: [
        { name: '颜色', values: ['红色', '蓝色', '绿色'] },
        { name: '尺寸', values: ['S', 'M', 'L'] }
      ],
      skus: [
        { id: 1, color: '红色', size: 'S', stock: 10, price: 100 },
        { id: 2, color: '红色', size: 'M', stock: 5, price: 120 },
        // 其他 SKU...
      ],
      selected: {},
      currentSku: null
    }
  },
  computed: {
    disabledValues() {
      const disabled = {}
      this.attributes.forEach(attr => {
        disabled[attr.name] = attr.values.filter(value => {
          const tempSelected = { ...this.selected, [attr.name]: value }
          return !this.hasStockForCombination(tempSelected)
        })
      })
      return disabled
    }
  },
  methods: {
    selectAttr(attrName, value) {
      this.$set(this.selected, attrName, value)
      this.checkAvailability()
    },
    checkAvailability() {
      const selectedCount = Object.keys(this.selected).length
      if (selectedCount === this.attributes.length) {
        this.currentSku = this.skus.find(sku => 
          this.attributes.every(attr => 
            sku[attr.name.toLowerCase()] === this.selected[attr.name]
          )
        )
      } else {
        this.currentSku = null
      }
    },
    hasStockForCombination(tempSelected) {
      return this.skus.some(sku => 
        this.attributes.every(attr => 
          sku[attr.name.toLowerCase()] === tempSelected[attr.name]
        )
      )
    }
  }
}
</script>

<style>
.active {
  background-color: #42b983;
  color: white;
}
.disabled {
  opacity: 0.5;
  cursor: not-allowed;
}
</style>

性能优化建议

对于大型 SKU 列表,可以考虑以下优化:

  • 使用 Map 或 Object 建立 SKU 的快速查找表
  • 对不可用选项进行缓存
  • 使用虚拟滚动处理大量属性值的情况

复杂场景处理

当属性之间存在依赖关系时(如某些颜色没有某些尺寸),需要额外处理:

vue实现sku选择

methods: {
  filterAvailableValues(attrName) {
    if (!this.selected[attrName]) return this.attributes.find(a => a.name === attrName).values

    return this.attributes.find(a => a.name === attrName).values.filter(value => {
      const tempSelected = { ...this.selected, [attrName]: value }
      return this.hasStockForCombination(tempSelected)
    })
  }
}

以上实现提供了基本的 SKU 选择功能,可根据实际需求进行调整和扩展。

标签: vuesku
分享给朋友:

相关文章

vue实现公式

vue实现公式

在Vue中实现公式展示或计算可以通过多种方式实现,以下为具体方法: 使用模板插值与计算属性 若公式较简单,可直接在模板中使用插值表达式或计算属性。例如计算圆的面积: <templat…

vue实现fadein

vue实现fadein

Vue 实现 FadeIn 效果 在 Vue 中实现淡入(FadeIn)效果可以通过 CSS 过渡、动画或第三方库实现。以下是几种常见方法: 使用 CSS 过渡 通过 Vue 的过渡系统结合 CSS…

vue实现签章

vue实现签章

Vue 实现签章功能 签章功能通常包括手写签名、电子印章等。以下是基于 Vue 的实现方法: 使用 canvas 实现手写签名 安装依赖(如需要): npm install signatu…

vue实现数组

vue实现数组

Vue 实现数组操作的方法 在 Vue 中,数组的操作需要特别注意响应式的问题。Vue 提供了一些方法来确保数组的变动能够触发视图更新。 响应式数组方法 Vue 对以下数组方法进行了封装,确保它们能…

tabbar 实现 vue

tabbar 实现 vue

在 Vue 中实现 TabBar 功能可以通过多种方式完成,以下是几种常见的方法: 使用 Vue Router 结合自定义组件 创建一个自定义的 TabBar 组件,结合 Vue Router 实现…

实现vue datepicker

实现vue datepicker

安装依赖 使用 vue-datepicker 或第三方库如 v-calendar 或 vue2-datepicker。以 vue2-datepicker 为例: npm install vue2…