You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vuetify Autocomplete组件中如何过滤重复模板项

解决Autocomplete组件的重复项与批量选中问题

咱们先拆解你遇到的两个问题,一步步给出具体的解决方案:

一、去除下拉列表的重复项

你当前直接把原始数组传给所有Autocomplete,自然会出现重复值——因为原始数组里的多个对象可能在目标属性上有相同的值。不要在模板里做过滤,应该在传给组件前就处理好数据,这更符合Vue的数据流逻辑,也更高效。

实现思路

针对每个Autocomplete的label,先从原始数组中提取对应属性的所有值,通过Set快速去重,再整理成组件需要的结构(如果需要保留完整对象,就取每个唯一值对应的第一个对象实例)。

具体代码示例

假设你的原始数据数组叫rawItems,可以在组件的计算属性里为每个label生成去重后的选项:

computed: {
  getFilteredItems() {
    return (targetLabel) => {
      const propKey = targetLabel.replace('filters.', '')
      // 用Set去重属性值,再转回数组
      const uniqueValues = [...new Set(this.rawItems.map(item => item.properties[propKey]))]
      // 映射回完整的item对象(取每个唯一值对应的第一个对象)
      return uniqueValues.map(value => {
        return this.rawItems.find(item => item.properties[propKey] === value)
      })
    }
  }
}

然后在模板里给每个Autocomplete传处理后的数组:

<Autocomplete 
  :items="getFilteredItems(label)"
  :label="label"
  <!-- 其他props -->
>
  <!-- 你的自定义item模板 -->
</Autocomplete>

这样每个Autocomplete拿到的都是去重后的选项,下拉列表就不会有重复项了。

二、解决选中一项全选的问题

这个问题的核心是所有复选框共享了同一个选中状态判断逻辑——你的isChecked(item)方法没有区分不同Autocomplete组件的选中项,也没有为每个组件维护独立的选中集合。

实现思路

为每个Autocomplete组件维护独立的选中状态,比如用一个对象存储,key是组件的label,value是该组件下选中的项集合(用Set操作更高效)。

具体代码示例

  1. 在data中初始化选中状态存储:
data() {
  return {
    selectedItems: {} // 结构:{ [label]: Set }
  }
}
  1. 修改选中判断和切换方法,加入label区分:
methods: {
  isChecked(item, label) {
    const propKey = label.replace('filters.', '')
    const targetValue = item.properties[propKey]
    // 若当前label无选中集合,初始化一个Set
    if (!this.selectedItems[label]) {
      this.selectedItems[label] = new Set()
    }
    return this.selectedItems[label].has(targetValue)
  },
  toggleCheck(item, label) {
    const propKey = label.replace('filters.', '')
    const targetValue = item.properties[propKey]
    if (!this.selectedItems[label]) {
      this.selectedItems[label] = new Set()
    }
    // 切换选中状态
    this.selectedItems[label].has(targetValue) 
      ? this.selectedItems[label].delete(targetValue) 
      : this.selectedItems[label].add(targetValue)
  }
}
  1. 更新模板,给方法传入label参数:
<template #item="{ item }">
  <v-list-item-action>
    <v-checkbox 
      :input-value="isChecked(item, label)"
      @change="toggleCheck(item, label)"
    ></v-checkbox>
  </v-list-item-action>
  <v-list-item-content @click="toggleCheck(item, label)">
    <span class="pr-2"> {{ item.properties[label.replace('filters.', '')] }} </span>
  </v-list-item-content>
</template>

这样每个Autocomplete的选中状态都是独立的,点击一个选项只会影响当前组件内的选中状态。

关于你的实现方式的小建议

你的自定义模板思路是没问题的,但数据处理尽量放在逻辑层(computed/methods)而非模板中,模板只负责渲染逻辑层处理好的数据,这样代码更清晰,也更容易维护调试。

内容的提问来源于stack exchange,提问作者Jérôme BORGA

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 15:52:41