Если вы посмотрите на их компонент автозаполнения: https://mui.com/material-ui/react-autocomplete/
После того, как вы щелкнете предложение в раскрывающемся списке, поле ввода останется в фокусе... Как они это делают? В каждом варианте этого в моем собственном приложении vue (без использования пользовательского интерфейса материала) я не могу получить событие щелчка, чтобы предотвратить потерю фокуса ввода.
Я пытался найти это в Google в течение достаточно долгого времени, и я не вижу четкого решения. Например, люди предлагают mousedown/touchstart, но это нарушит прокрутку (через перетаскивание раскрывающегося списка). У MaterialUI, очевидно, нет этой проблемы, и, похоже, он не использует mousedown.
Я пытался анализировать события с помощью инструментов разработчика Chrome, и я вижу только одно событие щелчка, но с уменьшенным кодом трудно сказать, что происходит.
Vuetify также делает это: https://github.com/vuetifyjs/vuetify/blob/master/packages/vuetify/src/components/VAutocomplete/VAutocomplete.ts
Я тоже нашел это полезным, если кто-то столкнется с этой проблемой https://codepen.io/Pineapple/pen/MWBVqGW
Изменить Вот что я делаю:
<app-input-autocomplete
@autocomplete-select = "onSelect"
@autocomplete-close = "onClose"
:open = "open">
<template #default = "{ result }">
<div class = "input-autocomplete-address">
{{ result.address }}
</div>
</template>
</app-input-autocomplete>
а затем в app-input-autocomplete
:
<template>
<app-input
@focus = "onFocus"
@blur = "onBlur"
v-bind = "$attrs">
<template #underInput>
<div ref = "dropdown" v-show = "open" class = "input-autocomplete-dropdown">
<div class = "input-autocomplete-results">
<div v-for = "result in results" :key = "result.id" @click = "onClick(result)" class = "input-autocomplete-result">
<slot :result = "result" />
</div>
</div>
</div>
</template>
</app-input>
</template>
<script>
import { ref, toRef } from 'vue';
import AppInput from '@/components/AppInput.vue';
import { onClickOutside } from '@vueuse/core';
export default {
components: {
AppInput,
},
inheritAttrs: false,
props: {
open: {
type: Boolean,
default: false,
},
results: {
type: Array,
default: () => ([]),
},
},
emits: ['autocomplete-close', 'autocomplete-select'],
setup(props, { emit }) {
const dropdown = ref(null);
const open = toRef(props, 'open');
const focused = ref(false);
onClickOutside(dropdown, () => {
if (!focused.value && open.value) {
emit('autocomplete-close');
}
});
return {
dropdown,
focused,
};
},
methods: {
onFocus() {
this.focused = true;
},
onBlur() {
this.focused = false;
},
onClick(result) {
this.$emit('autocomplete-select', result);
},
},
};
</script>
на основе кода в github, github.com/mui/material-ui/blob/master/packages/mui-base/src/… кажется, что они предоставляют специальное событие для обработки, когда происходит blur
. Сейчас у меня нет времени на глубокое погружение, но я надеюсь, что это укажет вам правильное направление. Похоже, они вызывают это событие для onBlur()
, а затем используют флаги других событий, чтобы определить, когда они могут сохранить фокус.
а здесь на github.com/mui/material-ui/blob/master/packages/mui-base/src/… они используют preventDefault()
.
Я решил это, сделав следующее, спасибо @Claies за идею посмотреть, а также эту ссылку:
https://codepen.io/Pineapple/pen/MWBVqGW
event.preventDefault
на mousedown
open = true
@LawrenceCherone Я добавил свой источник для компонента автозаполнения vue, который я создаю вручную