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

如何使用Vuetify的v-select实现下拉条目展示与输入搜索功能?

问题

我希望在Vuetify的v-select组件中同时实现两个功能:

  1. 以折叠/展开的形式展示选项条目(比如分组树形结构)
  2. 支持在输入框中输入文本,对选项进行搜索过滤

请问Vuetify有没有现成的prop可以直接实现,或者有什么实用的实现技巧?

当前使用的v-select代码如下:

<v-select
  v-model="searchParams.importApples"
  label="Importapples"
  :items="importApplesItems"
  :menu-props="{ bottom: true, offsetY: true }"
  item-text="label"
  item-value="value"
  filterable
  clearable
  outlined
  dense
/>
解决方案

一、原生分组折叠+搜索(适合简单分组场景)

Vuetify的v-select支持通过分组数据结构结合group-by prop实现折叠分组,同时保留filterable的搜索功能。

  1. 调整数据结构,给每个选项添加分组标识字段(比如group):
const importApplesItems = [
  { label: '红富士', value: 'red-fuji', group: '国产苹果' },
  { label: '花牛', value: 'huaniu', group: '国产苹果' },
  { label: '蛇果', value: 'red-delicious', group: '进口苹果' },
  { label: '青苹果', value: 'granny-smith', group: '进口苹果' }
]
  1. 修改v-select组件,添加group-by和group-filter prop(可选,控制分组是否随搜索过滤):
<v-select
  v-model="searchParams.importApples"
  label="Importapples"
  :items="importApplesItems"
  :menu-props="{ bottom: true, offsetY: true }"
  item-text="label"
  item-value="value"
  group-by="group"
  group-filter="label" // 搜索时过滤分组下的选项,空分组自动隐藏
  filterable
  clearable
  outlined
  dense
/>
  • 效果:选项按group字段自动分组,每个分组默认可折叠/展开,输入框的搜索会实时过滤分组内的选项,无匹配项的分组会自动隐藏。

二、自定义树形折叠+搜索(适合多级树形结构)

如果需要更复杂的多级树形折叠(父节点嵌套子节点),可以通过v-select的自定义菜单模板结合v-treeview实现,同时绑定搜索逻辑:

  1. 准备树形结构的数据:
const importApplesItems = [
  {
    id: 'domestic',
    name: '国产苹果',
    children: [
      { id: 'red-fuji', name: '红富士' },
      { id: 'huaniu', name: '花牛' }
    ]
  },
  {
    id: 'imported',
    name: '进口苹果',
    children: [
      { id: 'red-delicious', name: '蛇果' },
      { id: 'granny-smith', name: '青苹果' }
    ]
  }
]
  1. 修改v-select组件,自定义菜单内容并嵌入v-treeview:
<v-select
  v-model="searchParams.importApples"
  label="Importapples"
  :menu-props="{ bottom: true, offsetY: true, maxHeight: 400 }"
  clearable
  outlined
  dense
  @update:search-input="handleSearch" // 监听输入框的搜索文本
>
  <template v-slot:menu="{ props }">
    <v-treeview
      v-bind="props"
      :items="filteredItems"
      item-key="id"
      item-text="name"
      open-on-click
      activatable
      selectable
      @update:active="(active) => searchParams.importApples = active[0]"
    />
  </template>
</v-select>
  1. 实现搜索过滤逻辑:
import { ref, computed } from 'vue'

const searchParams = ref({ importApples: '' })
const importApplesItems = ref([/* 树形数据 */])
const searchText = ref('')

const filteredItems = computed(() => {
  if (!searchText.value) return importApplesItems.value

  // 递归过滤树形数据,保留包含搜索文本的节点及其父节点
  const filterTree = (items) => {
    return items.map(item => {
      const filteredChildren = item.children ? filterTree(item.children) : []
      const matches = item.name.includes(searchText.value) || filteredChildren.length > 0
      return matches ? { ...item, children: filteredChildren } : null
    }).filter(Boolean)
  }

  return filterTree(importApplesItems.value)
})

const handleSearch = (val) => {
  searchText.value = val
}
  • 效果:菜单内展示可折叠的树形结构,输入框文本会实时过滤树形节点,匹配的节点及其父节点会被保留显示。

关键注意点

  • 第一种方案适合简单一级分组,无需额外代码,完全依赖Vuetify原生prop实现;
  • 第二种方案适合多级树形结构,需要自定义菜单和过滤逻辑,但灵活性更高;
  • 两种方案都保留了v-select的核心交互(如v-model绑定、清空按钮等)。

内容的提问来源于stack exchange,提问作者Saturday Sun

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 23:55:30