如何保持 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>
我正在努力创建一个地理编码组件,允许用户使用 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>