当前位置:首页 > 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 对象。

vue实现sku选择

<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]
        )
      )
      // 处理匹配结果...
    }
  }
}

禁用不可选选项

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

vue实现sku选择

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

标签: vuesku
分享给朋友:

相关文章

vue实现autocomplete

vue实现autocomplete

Vue 实现 Autocomplete 功能 Vue 中实现 Autocomplete(自动完成)功能可以通过自定义组件或使用现有库完成。以下是几种常见方法: 方法一:使用 Vue 原生实现 创建…

vue实现rtc

vue实现rtc

Vue 实现 RTC 的步骤 安装依赖 在 Vue 项目中安装 WebRTC 相关依赖,如 simple-peer 或 peerjs,用于简化 WebRTC 的实现。 运行以下命令安装 simple-…

vue实现博客

vue实现博客

Vue 实现博客的基本步骤 使用 Vue.js 实现一个博客系统可以分为前端和后端两部分。以下是基于 Vue 的前端实现方案,后端可以选择 Node.js、Django 或其他框架。 项目初始化 使…

vue 实现工具

vue 实现工具

Vue 实现工具的方法 使用 Vue 实现工具功能可以通过多种方式完成,具体取决于工具的类型和需求。以下是几种常见的方法: 组件化实现 创建一个独立的 Vue 组件来封装工具功能。例如,实现一个计…

vue实现选人

vue实现选人

实现选人功能的基本思路 在Vue中实现选人功能通常涉及以下核心环节:数据绑定、用户交互处理、状态管理以及界面渲染。以下是具体实现方法: 数据准备与组件结构 创建包含人员信息的数组,通常从API获取或…

vue实现白板

vue实现白板

Vue实现白板功能 使用Vue实现白板功能可以通过HTML5的Canvas API结合Vue的响应式特性来完成。以下是实现白板功能的关键步骤: 安装依赖 在Vue项目中安装必要的依赖,如vue-dr…