当前位置:首页 > 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 的快速查找表
  • 对不可用选项进行缓存
  • 使用虚拟滚动处理大量属性值的情况

复杂场景处理

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

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 选择功能,可根据实际需求进行调整和扩展。

vue实现sku选择

标签: vuesku
分享给朋友:

相关文章

vue实现分类

vue实现分类

Vue实现分类功能的方法 使用v-for和计算属性 通过计算属性对数据进行分类处理,结合v-for渲染分类后的列表。示例代码: <template> <div>…

vue 实现拖拽

vue 实现拖拽

Vue 实现拖拽功能 使用 HTML5 原生拖拽 API HTML5 提供了原生的拖拽 API,可以通过 draggable 属性和相关事件实现拖拽功能。 <template> &l…

vue实现ios

vue实现ios

Vue 实现 iOS 风格应用 使用 Vue 实现 iOS 风格的应用,可以通过结合 UI 框架和自定义样式来达成目标。以下是具体方法和步骤: 选择 iOS 风格的 UI 框架 Vue 生态中…

vue实现双向

vue实现双向

Vue 实现双向绑定的方法 Vue 的双向绑定主要通过 v-model 指令实现,它结合了数据绑定和事件监听,适用于表单元素(如 input、select、textarea 等)。以下是几种常见的实现…

vue实现日历

vue实现日历

Vue 实现日历的基本方法 使用 Vue 实现日历可以通过自定义组件或借助第三方库完成。以下是两种常见实现方式: 自定义日历组件 创建基于 Vue 的日历组件需要处理日期计算和渲染逻辑。核心是生成…

vue实现树形

vue实现树形

Vue 实现树形组件 在 Vue 中实现树形结构通常需要递归组件和动态数据绑定。以下是实现树形组件的几种常见方法。 递归组件实现 递归组件是 Vue 中实现树形结构的核心方法。通过组件调用自身,可以…