iis服务器助手广告广告
返回顶部
首页 > 资讯 > 前端开发 > JavaScript >Vue3指令之搜索框输入防抖功能实现
  • 415
分享到

Vue3指令之搜索框输入防抖功能实现

vue输入防抖动vue中使用防抖Vue3搜索框输入防抖 2022-12-29 12:12:58 415人浏览 独家记忆
摘要

目录前言防抖 & 节流防抖节流输入防抖存在的问题指令实现总结前言 「搜索?」这个场景在各种业务的系统中都是是非常常见的,比如电商平台的商品搜索、百度搜索、掘金搜索、Googl

前言

「搜索?」这个场景在各种业务的系统中都是是非常常见的,比如电商平台的商品搜索、百度搜索、掘金搜索、Google搜索......,只要是有内容呈现给用户的,都少不了搜索功能。

按照触发搜索动作的不同可分为:

  • 输完关键字后手动触发搜索
  • 输入字符自动搜索

第一种是由用户去决定何时进行搜索,没啥问题。

第二种是通过监听用户录入的事件自动搜索,自动搜索能在一定程度上提升用户体验(比如在用户输入时关键词联想提示),同时也可能会带来问题,因为input事件触发是非常频繁的,比如下面这个示例:

打开百度的搜索,找到输入框的dom,然后绑定一个input事件,看看我们录入一个telephone会触发多少次input事件:

temp1.addEventListener('oninput', (val) => console.log(val))

触发了10次:

那如果每触发一次都会调用后台接口查询,那当用户量足够大,就会给后台服务器带来很大的压力,导致接口响应慢,甚至引起服务器宕机,也会给用户带来不好的体验。

为了不引起过多请求给服务端造成压力,我们期望在用户在输入完以后再发起请求,那怎么判断用户是否输入完了❓

可以认为当用户在一个固定的时间内都没有录入字符是输入完成/暂时输入完成。这个是老生常谈的知识点了————「防抖」和「节流」。掘金有很多文章专门写这个的,笔者在此不过多描述,简单一笔带过说下笔者的看法。

防抖 & 节流

防抖

防抖的函数在调用后,如果在防抖时间内没有再次触发,就会在过了 防抖时间 后执行;如果在防抖时间内再次触发,不论触发多少次,执行的时机会一直往后延迟,直到满足最后一次调用时间 小于 当前时间减去防抖时间才会执行。

function debounce(fn, time) {
  let timer
  return function (...argu) {
    if (timer) {
      clearTimeout(timer)
      timer = null
    }
    timer = setTimeout(() => {
      fn(...argu)
      clearTimeout(timer)
      timer = null
    }, time)
  }
}

节流

节流函数在调用后,在设置的节流时间后执行一次,在此期间,不论触发多少次,都直接return了。

function throttle(fn, time) {
  let flag = true
  return function (...argu) {
    if (!flag) {
      return
    }
    flag = false
    let timer = setTimeout(() => {
      fn(...argu)
      flag = true
      clearTimeout(timer)
      timer = null
    }, time)
  }
}

再来看下加了防抖 & 节流 处理的input事件执行情况:

  • 防抖:

  • 防抖 + 节流:

从上面的两个图不难看出防抖 和节流的区别,节流的函数如果一直被触发,每隔一段时间执行一次。而防抖则是一直延迟,最后执行一次。

输入防抖存在的问题

上面的防抖函数执行貌似没啥问题,前提是我们输入的是英文,如果是中文输入就出问题了,看下图:

当中文输入的时候,即使已经防抖处理了,还可能会执行多次。接下来咱们进入正题了,如何实现输入防抖vue3指令(并解决中文输入触发多次的问题)。

指令实现

为什么要以指令的方式实现❓我能想到的有以下两点:

  • 将防抖处理的逻辑封装在指令内部重用,更易用。
  • 指令要支持input输入框,也要支持封装input的组件,也就是说需要进行底层 DOM 访问的逻辑,而这一点恰好是指令提供的能力之一。

需要补充Vue 指令相关知识的同学点这里自定义指令

期望使用方式:

<template>
  <input v-model="val" v-debounceInput:600="onInput" />
</template>

<script setup lang="ts">
import { ref } from 'vue'

const val = ref('')
function onInput(e: Event): void {
  console.log(e)
}
</script>

即指令的绑定值为 执行逻辑,指令参数为 防抖时长。

指令实现:

import { debounce, isFunction } from '../../utils/index'

let inputFunction: (event: Event) => {}

// 由于要同时支持 input 输入框和封装 input 的组件,因此需要去找到input这个元素。
function findInput(el: htmlElement): HTMLElement | null {
  const quene: HTMLElement[] = []
  quene.push(el)
  while (quene.length > 0) {
    const current = quene.shift()
    if (current?.tagName === 'INPUT') {
      return current
    }
    if (current?.childnodes) {
      quene.push(...current.childNodes)
    }
  }
  return null
}

export default {
  mounted(el: HTMLElement, binding: any) {
    const { value, arg } = binding
    if (value && isFunction(value)) {
      let timeout = 600
      if (arg && !Number.isNaN(arg)) {
        timeout = Number(arg)
      }
      inputFunction = debounce(value, timeout) // 执行函数防抖处理
      const input = findInput(el)
      el._INPUT = input
      if (input) {
        input.addEventListener('input', inputFunction)
      }
    }
  },
  beforeUnmount(el: HTMLElement) {
    if (el._INPUT) {
      el._INPUT.removeEventListener('input', inputFunction)
      el._INPUT = null
    }
  }
}

接着处理中文输入可能会触发多次的问题。可借助compositionstart和compositionend来实现。

  • 输入法编辑器开始新的输入合成时会触发 compositionstart 事件。例如,当用户使用拼音输入法开始输入汉字时,这个事件就会被触发。
  • 当文本段落的组成完成或取消时,compositionend 事件将被触发 (具有特殊字符的触发,需要一系列键和其他输入,如语音识别或移动中的字词建议)。

在一开始拼音输入法时就设置composing为true,因此在compositionEnd没有调用之前都不会执行函数,等compositionEnd调用,通过dispatchEvent派发一个input事件出去,保证逻辑一定会执行。

function compositionStart(event: CompositionEvent) {
  event.target.composing = true
}
function compositionEnd(e: CompositionEvent) {
  e.target.composing = false
  const event = new Event('input', { bubbles: true })
  e.target?.dispatchEvent(event)
}

export default {
  mounted(el: HTMLElement, binding: any) {
    //...
      if (input) {
        input.addEventListener('input', inputFunction)
        input.addEventListener('compositionstart', compositionStart)
        input.addEventListener('compositionend', compositionEnd)
      }
    //...
  },
  beforeUnmount(el: HTMLElement) {
    if (el._INPUT) {
      el._INPUT.removeEventListener('input', inputFunction)
      el._INPUT.removeEventListener('compositionstart', compositionStart)
      el._INPUT.removeEventListener('compositionend', compositionEnd)
    }
  }
}

防抖实现 & 判断是 function

export function debounce(input: (event: Event) => any, timeout: number): (this: HTMLElement, ev: Event) => any {
  let timer: string | number | nodejs.Timeout | undefined
  return (event: Event) => {
    // @ts-ignore
    if (event.target.composing === true) {
      return
    }
    if (timer) {
      clearTimeout(timer)
      timer = undefined
    }
    timer = setTimeout(() => {
      input(event)
      clearTimeout(timer)
      timer = undefined
    }, timeout)
  }
}

export function isFunction(param: any): boolean {
  return Object.prototype.toString.call(param) === '[object Function]'
}

注册指令(全局注册):

createApp(App).directive('debounceInput', debounceInput).mount('#app')

写个案例测试一下:

<template>
  <div>防抖</div>
  <input v-model="val" v-debounceInput="onInput" />
  <div>普通</div>
  <input v-model="count" type="text" @input="onInput" />
</template>

<script setup lang="ts">
import { ref } from 'vue'

const val = ref('')
const count = ref('')
function onInput(e: Event): void {
  console.log('调用了onInput')
}
</script>

看下最终的效果:

差别还是非常明显的。指令已发布npm仓库,有需要可自取。

总结

?感谢浏览,通过本文你可以了解到以下内容:

  • 防抖
  • 节流
  • Vue3指令开发
  • compositionstart 事件 (需要注意浏览器兼容性)
  • compositionend 事件(需要注意浏览器兼容性)

到此这篇关于Vue3指令之搜索框输入防抖功能实现的文章就介绍到这了,更多相关Vue3搜索框输入防抖内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: Vue3指令之搜索框输入防抖功能实现

本文链接: https://www.lsjlt.com/news/176201.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Vue3指令之搜索框输入防抖功能实现
    目录前言防抖 & 节流防抖节流输入防抖存在的问题指令实现总结前言 「搜索」这个场景在各种业务的系统中都是是非常常见的,比如电商平台的商品搜索、百度搜索、掘金搜索、google...
    99+
    2022-12-29
    vue输入防抖动 vue中使用防抖 Vue3搜索框输入防抖
  • java怎么实现搜索框搜索功能
    要实现搜索框搜索功能,可以按照以下步骤进行:1. 在前端页面上创建一个搜索框,如一个文本框和一个按钮。2. 在后端创建一个处理搜索请...
    99+
    2023-09-26
    java
  • Android实现实时搜索框功能
    AutoCompleteTextView,自动完成文本框。用于实现允许用户输入一定字符后,显示一个下拉菜单,供用户从中选择,当用户选择某个选项后,按用户选择自动填写该文本框。该组件继承EditText,所以它支持EditText组件提供的属...
    99+
    2023-05-30
    android 搜索框 roi
  • vue3中怎么自定义指令实现按钮防抖
    这篇“vue3中怎么自定义指令实现按钮防抖”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“vue3中怎么自定义指令实现按钮防抖...
    99+
    2023-07-05
  • Ajax实现搜索框提示功能
    html代码: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF...
    99+
    2024-04-02
  • vue3自定义指令实现按钮防抖示例详解
    目录写在前面自定义指令实现按钮防抖实现思路代码实现总结写在前面 在实际项目开发过程中,对于按钮的提交事件来说,我们需要限制按钮重复点击,避免在某个时间内重复提交。这时候我们一般用到...
    99+
    2023-02-27
    vue3自定义指令按钮防抖 vue 按钮防抖
  • css如何实现带搜索图标的搜索框功能
    这篇文章给大家分享的是有关css如何实现带搜索图标的搜索框功能的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。前言给大家分享一下前端用处很多的带小图标的搜索框的制作方法。效果展示基本思路搜索图像用绝对定位放到搜索框...
    99+
    2023-06-08
  • 微信小程序怎么实现搜索输入框带搜索记录
    本篇内容主要讲解“微信小程序怎么实现搜索输入框带搜索记录”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“微信小程序怎么实现搜索输入框带搜索记录”吧!  在最近的项目里有一个需求,就是需要一个带搜索...
    99+
    2023-06-26
  • 微信小程序实现搜索框功能
    本文实例为大家分享了微信小程序实现搜索框功能的具体代码,供大家参考,具体内容如下 效果: wxml文件: <view class="search_input" > ...
    99+
    2024-04-02
  • android简单搜索框功能怎么实现
    要实现一个简单的搜索框功能,可以按照以下步骤进行操作: 在布局文件中添加一个EditText作为搜索框,同时添加一个按钮用于触发搜...
    99+
    2024-03-11
    android
  • css如何实现输入自动提示搜索提示功能
    这篇文章将为大家详细讲解有关css如何实现输入自动提示搜索提示功能,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。代码如下:.sugLayerDiv{ position:relative;&nbs...
    99+
    2023-06-08
  • uniapp小程序之配置首页搜索框功能的实现
    目录正文1、查阅官网配置搜索框pages配置项1.1 首先进入官网后找到如下内容1.2 如官网所示 style的说明如下,看图操作1.3 跳转指定的app-plus配置项1.4 导航...
    99+
    2024-04-02
  • vue如何实现可搜索下拉框功能
    这篇文章主要为大家展示了“vue如何实现可搜索下拉框功能”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“vue如何实现可搜索下拉框功能”这篇文章吧。效果图:子组件...
    99+
    2024-04-02
  • flutter微信聊天输入框功能实现
    目录chat_bottom.dartchat_element_other.dart chat_element_self.dart  chat_input...
    99+
    2023-03-02
    flutter 微信聊天输入框 flutter 聊天输入框 flutter 输入框
  • Servlet+Ajax如何实现智能搜索框智能提示功能
    小编给大家分享一下Servlet+Ajax如何实现智能搜索框智能提示功能,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!利用无刷新技术智能变换搜索框的提示,同百度搜...
    99+
    2023-06-08
  • Flutter开发之支持放大镜的输入框功能实现
    目录功能需求需求调研需求实现源码解读功能复刻最终效果功能需求 最近需求开发中遇到一个Flutter开发问题,为了优化用户输入体验。产品同学希望能够在输入框支持在移动光标过程中可以出现...
    99+
    2024-04-02
  • PHP实现搜索框自动补全功能的方法
    搜索框自动补全是一种常见的网页功能,能够提升用户体验并简化搜索过程。在PHP中实现搜索框自动补全功能可以通过Ajax异步请求来实现。下面将介绍具体的实现方法,包括前端代码和后端代码示例...
    99+
    2024-03-07
    搜索框 php 自动补全
  • Vue3+Element+Ts实现表单的基础搜索重置等功能
    从Vue2的写法转变为Vue3的格式之后,会有一些写法和代码结构的改变,这里对一些重点进行介绍。 代码结构: 写法一(推荐): <script setup lang=...
    99+
    2024-04-02
  • 怎么使用vue实现可搜索下拉框功能
    本篇内容主要讲解“怎么使用vue实现可搜索下拉框功能”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“怎么使用vue实现可搜索下拉框功能”吧!效果图:子组件 DROPDOWN.VUE<...
    99+
    2023-07-04
  • shell命令行如何实现输入与输出功能
    这篇文章将为大家详细讲解有关shell命令行如何实现输入与输出功能,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。标准输入/输出和重定向,Linux发行版Fedora Core Linux,而Red Hat...
    99+
    2023-06-09
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作