web-dev-qa-db-fra.com

Vue.JS valeur liée à une entrée ayant le focus

Existe-t-il un moyen de modifier une valeur dans le modèle lorsqu'une entrée obtient/perd le focus?

Le cas d'utilisation ici est une entrée de recherche qui affiche les résultats au fur et à mesure de la frappe. Celles-ci ne doivent apparaître que lorsque la zone de recherche est active.

Voici ce que j'ai jusqu'à présent:

<input type="search" v-model="query">
<div class="results-as-you-type" v-if="magic_flag"> ... </div>

Et alors,

new Vue({
  el: '#search_wrapper',
  data: {
    query: '',
    magic_flag: false
  }
});

L'idée ici est que magic_flag devrait devenir true lorsque la zone de recherche a le focus. Je pourrais le faire manuellement (en utilisant jQuery, par exemple), mais je veux une solution Vue.JS pure.

24
cambraca

Apparemment, ceci est aussi simple que de faire un peu de code sur les gestionnaires d’événements .

<input 
  type="search" 
  v-model="query"
  @focus="magic_flag = true"
  @blur="magic_flag = false"
/>
<div class="results-as-you-type" v-if="magic_flag"> ... </div>
45
cambraca

Une autre façon de gérer quelque chose comme ceci dans un scénario plus complexe pourrait être d'autoriser le formulaire à déterminer quel champ est actuellement actif, puis à utiliser un observateur.

Je vais montrer un échantillon rapide:

<input
    v-model="user.foo"
    type="text"
    name="foo"
    @focus="currentlyActiveField = 'foo'"
>

<input
    ref="bar"
    v-model="user.bar"
    type="text"
    name="bar"
    @focus="currentlyActiveField = 'bar'"
>

...

data() {
    return {
        currentlyActiveField: '',
        user: {
            foo: '',
            bar: '',
        },
    };
},

watch: {
    user: {
        deep: true,
        handler(user) {
            if ((this.currentlyActiveField === 'foo') && (user.foo.length === 4)) {
                // the field is focused and some condition is met
                this.$refs.bar.focus();
            }
        },
    },
},

Dans mon exemple ici, si le champ actuellement actif est foo et que la valeur comporte 4 caractères, le champ suivant bar sera automatiquement activé. Ce type de logique est utile lorsqu'il s'agit de formulaires comportant des informations telles que le numéro de carte de crédit, l'expiration de la carte de crédit et la saisie du code de sécurité de la carte de crédit. L'UX peut être amélioré de cette façon.

J'espère que cela pourrait stimuler votre créativité. Les observateurs sont pratiques car ils vous permettent d’écouter les modifications apportées à votre modèle de données et d’agir en fonction de vos besoins personnalisés au moment du déclenchement de l’observateur.

Dans mon exemple, vous pouvez voir que chaque entrée est nommée et le composant sait quelle entrée est actuellement focalisée car il suit la currentlyActiveField.

L’observateur que j’ai montré est un peu plus complexe dans la mesure où c’est un observateur «profond», ce qui signifie qu’il est capable de regarder des objets et des tableaux. Sans deep: true, l'observateur ne serait déclenché que si user était réaffecté, mais nous ne le souhaitons pas. Nous surveillons les touches foo et bar sur user.

Dans les coulisses, deep: true ajoute des observateurs à toutes les touches de this.user. Sinon, Vue n’engage pas le coût de cette opération.

Un simple observateur serait comme ça:

watch: {
    user() {
        console.log('user changed');
    },
},

Remarque: Si vous découvrez que j'ai handler(user) {, vous pourriez avoir handler(oldValue, newValue) { mais vous remarquerez que les deux affichent la même valeur, c'est parce qu'ils font tous deux référence au même objet user. Lisez plus ici: https://github.com/vuejs/vue/issues/2164

0
agm1984

Vous pouvez également vouloir activer la recherche lorsque l'utilisateur passe la souris sur l'entrée - @mouseover = ...

Une autre approche de ce type de fonctionnalité est que l'entrée de filtre est toujours active, même lorsque la souris est dans la liste des résultats. Taper des lettres modifie l'entrée du filtre sans changer le focus. De nombreuses implémentations affichent en fait le champ de saisie du filtre uniquement après avoir tapé une lettre ou un chiffre.

Regardez dans @ event.capture.

0