Comment MaterialUI fait-il cela ?
P粉916760429
2023-09-04 18:17:31
<p>Si vous regardez leur composant de saisie semi-automatique : https://mui.com/material-ui/react-autocomplete/</p>
<p>La zone de saisie reste active après avoir cliqué sur une suggestion dans la liste déroulante... Comment font-ils cela ? Dans chaque variante de ma propre application vue (n'utilisant pas l'interface utilisateur matérielle), je ne parviens pas à obtenir l'événement de clic pour empêcher l'entrée de perdre le focus. </p>
<p>J'essaie de rechercher ce problème sur Google depuis longtemps, mais je n'ai pas trouvé de solution claire. Par exemple, les gens ont suggéré mousedown/touchstart, mais cela interrompt le défilement (en faisant glisser la liste déroulante). MaterialUI n'a apparemment pas ce problème et ne semble pas utiliser mousedown. </p>
<p>J'ai essayé d'analyser l'événement à l'aide des outils de développement Chrome, mais je ne peux voir qu'un événement en un seul clic, mais avec le code simplifié, il est difficile de dire ce qui se passe. </p>
<p>Vuetify fait cela aussi : https://github.com/vuetifyjs/vuetify/blob/master/packages/vuetify/src/components/VAutocomplete/VAutocomplete.ts</p>
<p>Si quelqu'un a ce problème, j'ai également trouvé ceci utile https://codepen.io/Pineapple/pen/MWBVqGW</p>
<p><strong>Modifier</strong>Voici ce que je fais : </p>
<pre class="brush:html;toolbar:false;">
@autocomplete-select="onSelect"
@autocomplete-close="onClose"
:open="ouvrir">
<template #default="{ résultat }">
<div class="input-autocomplete-address">
{{ résultat.adresse }}
</div>
</modèle>
</app-input-autocomplete>
≪/pré>
<p>Puis dans <code>app-input-autocomplete</code> : </p>
<pre class="brush:html;toolbar:false;"><template>
<entrée-application
@focus="onFocus"
@blur="onBlur"
v-bind="$attrs">
<modèle #underInput>
<div ref="dropdown" v-show="open" class="input-autocomplete-dropdown">
<div class="input-autocomplete-results">
<div v-for="résultat dans les résultats" :key="result.id" @click="onClick(result)" class="input-autocomplete-result">
<slot :result="résultat"
</div>
</div>
</div>
</modèle>
</entrée-application>
</modèle>
<script>
importer { ref, toRef } depuis 'vue' ;
importer AppInput depuis '@/components/AppInput.vue' ;
importer { onClickOutside } depuis '@vueuse/core';
exporter par défaut {
Composants: {
Entrée d'application,
},
hériterAttrs : faux,
accessoires : {
ouvrir: {
tapez: booléen,
par défaut : faux,
},
résultats: {
tapez : tableau,
par défaut : () => ([]),
},
},
émet : ['autocomplete-close', 'autocomplete-select'],
setup(accessoires, {émettre}) {
const liste déroulante = ref(null);
const open = toRef(props, 'open');
const focus = ref(false);
onClickOutside(dropdown, () => {
if (!focused.value && open.value) {
émettre('autocomplete-close');
}
});
retour {
dérouler,
concentré,
} ;
},
méthodes : {
onFocus() {
this.focused = vrai ;
},
le flou() {
this.focused = faux ;
},
onClick (résultat) {
this.$emit('autocomplete-select', résultat);
},
},
} ;
</script>
</pre></p>
J'ai résolu ce problème en procédant comme suit, merci à @Claies pour l'idée et ce lien :
https://codepen.io/Pineapple/pen/MWBVqGW
event.preventDefault
onmousedown
open = true