Vue 自定义指令来实现监听 input 输入,但是你需要配合一些 JavaScript 代码才能实现输入完成后才调用接口的逻辑。

下面是一个简单的实现示例:

<template>
  <div>
    <input v-model="inputValue" v-debounce-input:500ms="getData" />
  </div>
</template>

<script>
export default {
  data() {
    return {
      inputValue: '',
      timer: null
    }
  },
  methods: {
    getData() {
      // 在这里编写调用接口的代码
      console.log('调用接口', this.inputValue)
    }
  },
  directives: {
    'debounce-input': {
      inserted(el, binding) {
        let timeout
        el.addEventListener('input', () => {
          clearTimeout(timeout)
          timeout = setTimeout(() => {
            binding.value()
          }, parseInt(binding.arg) || 300)
        })
      }
    }
  }
}
</script>

在上面的示例中,我们定义了一个自定义指令叫做 v-debounce-input。该指令监听了 input 事件,并使用 setTimeout 实现了防抖的逻辑,从而在用户输入完成之后才会调用 getData 方法。同时,我们还在指令的参数中使用了 500ms,表示用户输入完成后需要等待 500 毫秒才会调用 getData

需要注意的是,上面的代码中使用了一个 timer

总结一下,自定义指令可以用来监听 input 输入,并使用防抖的方式来实现在用户输入完成后才调用接口的逻辑。这样就可以避免频繁调用接口的问题,提高应用的性能和用户体验。

clearTimeout(timeout) 的作用是清除一个之前通过 setTimeout

在上述示例中,clearTimeout(timeout) 的作用是清除上一次输入事件触发的定时器,这样可以避免在用户输入新的内容时,上一次的定时器依然在计时,导致多次调用 getData

由于 clearTimeout 方法不会影响下一行代码的执行,因此在这个示例中,clearTimeout(timeout) 和 timeout = setTimeout(() => {binding.value()}, parseInt(binding.arg) || 300) 可以被认为是独立的两个操作,它们之间没有任何影响。具体来说,当用户输入新的内容时,clearTimeout(timeout) 会立即清除上一次触发的定时器,而 timeout = setTimeout(() => {binding.value()}, parseInt(binding.arg) || 300) 则会创建一个新的定时器,等待指定的时间后再执行 binding.value()

需要注意的是,由于 JavaScript 是单线程执行的,因此定时器的回调函数执行时会阻塞主线程,如果回调函数执行时间过长,会影响用户体验。因此,一般来说应该尽可能缩短定时器的等待时间,避免出现长时间的阻塞。

在 Vue.js 中,指令(Directive)是一种带有 v- 前缀的特殊属性。指令用于在模板中添加特殊行为,例如控制元素的显示和隐藏、监听事件、绑定属性等。

其中,inserted 方法是指令钩子函数之一,它会在被绑定的元素插入到父元素中时调用。inserted 方法的定义如下:

inserted(el, binding, vnode, oldVnode) {
  // ... 
}

inserted 方法接收四个参数:

  • el:指令绑定的元素。
  • binding:一个对象,包含指令的信息。可以访问指令的值、参数、修饰符等。
  • vnode:Vue 编译生成的虚拟节点。
  • oldVnode:上一个虚拟节点,仅在 componentUpdated 和 update

inserted

需要注意的是,如果指令所绑定的元素是动态生成的,例如通过 v-if、v-for 等指令动态生成的元素,那么 inserted

binding对象怎么用?

在 Vue.js 中,指令钩子函数的第二个参数是一个对象,用于获取指令的相关信息。这个对象被称为 binding 对象。

binding 对象包含以下属性:

  • name:指令名称,不包括 v- 前缀。
  • value:指令的绑定值。
  • oldValue:指令的前一个绑定值,仅在 update 和 componentUpdated
  • expression:指令的绑定表达式。
  • arg:指令的参数,没有参数则为 null。
  • modifiers:一个对象,包含指令的修饰符。

可以通过 binding.value

Vue.directive('my-directive', {
  inserted(el, binding) {
    console.log(binding.value) // 输出指令的绑定值
  }
})

指令的绑定值可以是一个字符串、一个对象、一个数组、一个函数等任何类型的值。在实际使用中,可以根据不同的指令需求,使用不同类型的绑定值,并在钩子函数中根据绑定值来进行相关操作。

除了 binding.value,还可以通过 binding.arg 获取指令的参数,通过 binding.modifiers

Vue.directive('my-directive', {
  inserted(el, binding) {
    console.log(binding.arg) // 输出指令的参数
    console.log(binding.modifiers) // 输出指令的修饰符
  }
})

需要注意的是,如果指令没有参数和修饰符,那么 binding.arg 和 binding.modifiers 将分别为 null 和 {}