如何保持 Quasar Select 组件的弹出窗口打开?

How to keep popup of Quasar Select component open?

我正在努力创建一个地理编码组件,允许用户使用 Quasar 的 <q-select /> 组件搜索他们的地址。但是,我 运行 遇到了弹出窗口的一个问题。

用户输入搜索查询后,我从 API 中获取结果并将结果设置为反应性本地状态(填充 select 的选项)。虽然弹出窗口没有显示,但它关闭了,我必须点击人字形图标两次才能让弹出窗口显示结果。

第一张图片是我第一次点击输入时的样子。

第二张图片显示了输入查询后发生的情况。获取数据、设置选项并关闭弹出窗口。

第三张图片显示了 select 单击 V 形图标两次后。

如何以编程方式显示弹出窗口,以便在获取结果后正确显示弹出窗口?

编辑: 创建了一个工作重现 here

<template>
  <q-select
    ref="geolocateRef"
    v-model="state.location"
    :options="state.locations"
    :loading="state.loadingResults"
    clear-icon="clear"
    dropdown-icon="expand_more"
    clearable
    outlined
    :use-input="!state.location"
    dense
    label="Location (optional)"
    @clear="state.locations = undefined"
    @input-value="fetchOptions">
      <template #prepend>
        <q-icon name="place " />
      </template>
      <template #no-option>
        <q-item>
          <q-item-section class="text-grey">
            No results
          </q-item-section>
        </q-item>
      </template>
    </q-select>
</template>

<script lang='ts' setup>
  import { reactive } from 'vue';
  import { debounce, QSelect } from 'quasar';
  import { fetchGeocodeResults } from '@/services';

  const state = reactive({
    location: undefined as string | undefined,
    locations: undefined,
    loadingResults: false,
    geolocateRef: null as QSelect | null,
  });

  const fetchOptions = debounce(async (value: string) => {
    if (value) {
      state.loadingResults = true;
      const results = await fetchGeocodeResults(value);

      state.locations = results.items.map(item => ({
        label: item.title,
        value: JSON.stringify(item.position),
      }));

      state.loadingResults = false;
      state.geolocateRef?.showPopup(); // doesn't work?
    }
  }, 500);
</script>

我也在 Quasar Github discussions 中发布了这个问题,有人发布了一个绝妙的解决方案。

<template>
  <q-select
    v-model="state.location"
    :use-input="!state.location"
    input-debounce="500"
    label="Location (optional)"
    :options="options"
    dense
    clear-icon="bi-x"
    dropdown-icon="bi-chevron-down"
    clearable
    outlined
    @filter="fetchOptions">
    <template #prepend>
      <q-icon name="bi-geo-alt" />
    </template>
    <template #no-option>
      <q-item>
        <q-item-section class="text-grey">
          No results
        </q-item-section>
      </q-item>
    </template>
  </q-select>
</template>

<script lang='ts' setup>
  import { reactive, ref } from 'vue';
  import { QSelect } from 'quasar';
  import { fetchGeocodeResults } from '@/services';

  interface Result {
    position: {
      lat: number;
      lng: number;
    }
    title: string;
  }

  const state = reactive({
    ...other unrelated state,
    location: undefined as string | undefined,
  });

  const options = ref([]);

  const fetchOptions = async (val: string, update) => {
    if (val === '') {
      update();
      return;
    }

    const needle = val.toLowerCase();
    const results = await fetchGeocodeResults(needle);

    options.value = results.items.map((item: Result) => ({
      label: item.title,
      value: JSON.stringify(item.position),
    }));

    update();
  };
</script>