首页 > 解决方案 > 当用户在 Vue.js 的搜索字段中输入一些文本时,我应该使用哪个事件来做出反应?

问题描述

我有一个文本字段(取自 vuetify 库),用于过滤我的应用程序中的某些表。

<v-text-field
  style="min-width: 300px;"
  v-model="filterString"
  label="Search" />

工作原理很简单——每次用户提供新的过滤值时,表格内容都要更新。没有提交按钮或类似的东西。过滤是在后端实现的,因此每次更新都需要向我的 API 发送请求。当过滤器字符串更新时,我使用 Vue.js 观察程序发送请求。

watch: {
  async filterString() {
    // some logic containing communication with my api
  },
},

假设我的应用程序的用户在搜索框中键入了大约 10 个字母字符串。然后,我的应用程序向我的 API 发送了 10 个请求,而忽略了前 9 个请求是无用的这一事实。这就是我的问题。我应该使用时钟,并且仅在经过一定时间后才发送请求吗?当用户完成输入时是否会触发一些我需要订阅的事件?仅当用户在我的框中输入完毕后如何发送请求?感谢您的任何回答。

标签: javascriptvue.jsfiltervuetify.js

解决方案


您正在寻找的东西称为去抖动。它只是一个等待你停止按键的计时器。

这是使用 lodash debounce 的快速方法

模板:

    <input
            :value="input"
            @change="evt=>textChange(evt.target.value)"
            @input="evt=>textEntry(evt.target.value)"               
    />

javascript:

进口:

 import { debounce } from 'lodash'

定义:

 model: {
    prop: 'input',
    event: 'input'
  },
 props: {
    input: {
      default: '',
      type: String
    },
    debounce: {
      default: -1,
      type: Number
    }
  },
 methods: {
    textChange (value) {
        this.$emit('input', value)
      }
    },
    textEntry (value) {
      // This is to cover for situations where the change event runs first
      if (value.toUpperCase() === this.input.toUpperCase()) return
      if (this.debounce >= 0) {
        this.emitValue(value)
      } else {
        this.$emit('input', value)
      }
    }
  },
  async mounted () {
    this.emitValue = debounce(value => {
      this.$emit('input', value)
    }, Math.abs(this.debounce))
    await this.$nextTick()
    this.textChange(this.input) // apply whatever was loaded, and allow bindings to run
  }

推荐阅读