recherche

Maison  >  Questions et réponses  >  le corps du texte

Méthode d'implémentation anti-shake dans Vue3

<p>J'ai une zone de saisie de filtre et je souhaite filtrer une liste d'éléments. La liste est longue, je souhaite donc utiliser l'antishake pour retarder l'application du filtre jusqu'à ce que l'utilisateur arrête de taper afin d'améliorer l'expérience utilisateur. Ceci est ma zone de saisie qui est liée à filterText pour filtrer la liste. </p> <pre class="brush:php;toolbar:false;"><input type="text" v-model="state.filterText" /></pre>
P粉055726146P粉055726146464 Il y a quelques jours634

répondre à tous(2)je répondrai

  • P粉879517403

    P粉8795174032023-08-25 11:20:55

    Bonjour, c'est la première fois que je réponds à une question ici, alors n'hésitez pas à corriger ma réponse, je vous en serai très reconnaissant. Je pense que la solution la plus belle et la plus légère consiste à créer globalement une directive que vous pouvez utiliser de manière aléatoire dans tous vos formulaires.

    Créez d'abord un fichier avec des directives, par exemple. debouncer.js

    Créez ensuite la fonction anti-shake

        //debouncer.js
        /*
          这是一个典型的防抖函数,它接收“callback”和等待发出事件的时间
        */
        function debouncer (fn, delay) {
            var timeoutID = null
            return function () {
              clearTimeout(timeoutID)
              var args = arguments
              var that = this
              timeoutID = setTimeout(function () {
                fn.apply(that, args)
              }, delay)
            }
          }
    
        /*
          此函数接收指令将设置在其中的元素和设置在其中的值
          如果值已更改,则重新绑定事件
          它具有默认超时时间为500毫秒
        */
        module.exports = function debounce(el, binding) {
          if(binding.value !== binding.oldValue) {
            el.oninput = debouncer(function(){
              el.dispatchEvent(new Event('change'))
            }, parseInt(binding.value) || 500)
          }
        }
    

    Après avoir défini ce fichier, vous pouvez vous rendre dans votre main.js pour l'importer et utiliser les fonctions exportées.

        //main.js
        import { createApp } from 'vue'
        import debounce from './directives/debounce' // 导入的文件
        
        const app = createApp(App)
    
        //定义指令
        app.directive('debounce', (el,binding) => debounce(el,binding))
    
        app.mount('#app')
    

    Terminé, lorsque vous souhaitez utiliser une directive dans une zone de saisie, faites-le comme ça, pas besoin d'importer ou quoi que ce soit d'autre.

        //Component.vue
        <input
           :placeholder="按名称筛选"
           v-model.lazy="filter.value" v-debounce="400"
        />
    

    La directive v-model.lazy est très importante si vous choisissez de procéder de cette façon, car par défaut elle mettra à jour les propriétés liées sur l'événement d'entrée, mais la définition de cette directive le fera attendre l'événement de changement, ce qui est le cas. l'événement que nous émettons dans la fonction anti-shake. Cela empêchera v-model de se mettre à jour automatiquement jusqu'à ce que vous arrêtiez la saisie ou que le délai d'attente expire (peut être défini dans la valeur de la directive). J'espère que cela est clair.

    répondre
    0
  • P粉550257856

    P粉5502578562023-08-25 10:05:26

    Je n'ai pas trouvé de solution satisfaisante car je voulais voir mes fixations dans le modèle, j'ai donc décidé de partager ma solution. J'ai écrit une simple fonction anti-rebond et lié le comportement en utilisant la syntaxe suivante :

    setup() {
    ...
    
      function createDebounce() {
        let timeout = null;
        return function (fnc, delayMs) {
          clearTimeout(timeout);
          timeout = setTimeout(() => {
            fnc();
          }, delayMs || 500);
        };
      }
    
      return {
        state,
        debounce: createDebounce(),
      };
    },
    

    La syntaxe du modèle est la suivante :

        <input
          type="text"
          :value="state.filterText"
          @input="debounce(() => { state.filterText = $event.target.value })"
        />
    

    répondre
    0
  • Annulerrépondre