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

Nuxt项目中Vuetify Autocomplete下拉框不实时显示搜索结果问题

问题原因

导致输入后下拉框不实时展示的核心原因有2个:

  • Vuetify Autocomplete默认开启了前端过滤逻辑,你从后端拿到匹配结果后,组件会用当前输入的字符再做一次前端过滤,很容易出现误判无匹配结果、隐藏下拉菜单的情况,只有重新聚焦时才会重新计算展示。
  • 你监听搜索词的watch中存在无效逻辑,且数组更新方式可能触发响应式更新延迟。
修复方案

第一步:修改模板代码

给v-autocomplete组件添加no-filter属性,禁用前端默认过滤,可选添加menu-props保证菜单正常弹出:

<v-autocomplete 
  v-model="pickupairport" 
  name="pickupairport" 
  :items="airports" 
  :loading="isLoading" 
  :search-input.sync="aptsearch" 
  chips 
  clearable 
  hide-details 
  hide-selected 
  label="Search for a airport..." 
  solo
  no-filter
  :menu-props="{ openOnClick: true, closeOnContentClick: false }"
>
  <!-- 原有slot代码保持不变 -->
  <template v-slot:no-data>
      <v-list-item>
          <v-list-item-title>
              Search for your favorite
              <strong>Destinations</strong>
          </v-list-item-title>
      </v-list-item>
  </template>
  <template v-slot:selection="{ attr, on, item, selected }">
      <v-chip v-bind="attr" :input-value="selected" color="blue-grey" class="white--text" v-on="on">
          <v-icon left>
              mdi-bitcoin
          </v-icon>
          <span v-text="item.name"></span>
      </v-chip>
  </template>
  <template v-slot:item="{ item }">
      <v-list-item-avatar color="indigo" class="text-h5 font-weight-light white--text">
          {{ item.name.charAt(0) }}
      </v-list-item-avatar>
      <v-list-item-content>
          <v-list-item-title v-text="item.name"></v-list-item-title>
          <v-list-item-subtitle>{{item.cityName}}, {{item.countryName}}</v-list-item-subtitle>
      </v-list-item-content>
      <v-list-item-action>
          <v-icon>fa-airports</v-icon>
      </v-list-item-action>
  </template>
</v-autocomplete>

第二步:修改script逻辑

删除watch中无效的判断逻辑,优化数组赋值方式,可选添加防抖避免频繁请求:

export default {
  data() {
    return {
      aptsearch: null,
      items: [],
      model: null,
      tab: null,
      pickupairport: '',
      airports: [],
      isLoading: false,
      uuid: this.$uuid.v4(),
      searchTimer: null // 新增防抖定时器变量
    }
  },
  watch: {
    model(val) {
      if (val != null) this.tab = 0
      else this.tab = null
    },
    aptsearch(val) {
      // 防抖逻辑:300ms内重复输入不发请求
      if (this.searchTimer) clearTimeout(this.searchTimer)
      // 输入为空时直接清空结果不发请求
      if (!val || val.trim().length === 0) {
        this.airports = []
        return
      }

      this.searchTimer = setTimeout(() => {
        this.isLoading = true
        // 原有请求逻辑
        fetch(`${process.env.EXPRESS_API_URL}/airports/find`, {
          method: "post",
          headers: {
            'Accept': 'application/json',
            'Content-Type': 'application/json'
          },
          body: JSON.stringify({
            aptsearchkey: val
          })
        })
        .then(response => response.json())
        .then((data) => {
          // 直接赋值数组,触发响应式更新
          this.airports = data
        })
        .catch(err => {
          console.log(err)
        })
        .finally(() => (this.isLoading = false))
      }, 300)
    },
  }
}
改动说明
  • no-filter:禁用组件默认的前端过滤,完全使用后端返回的匹配结果展示,避免过滤逻辑冲突导致下拉隐藏
  • 防抖逻辑:避免每次输入都触发API请求,减少后端压力,也避免频繁更新数组导致组件渲染异常
  • 直接赋值数组:比循环push的响应式触发更稳定,保证组件可以立即检测到airports数组的变化,自动弹出下拉菜单

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 22:54:08