最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Vue3指令之搜索框輸入防抖功能實現(xiàn)

 更新時間:2022年12月29日 11:20:54   作者:Lvzl  
在Vue開發(fā)中遇到了搜索框輸入防抖處理,算是防抖的使用場景之一吧,這篇文章主要給大家介紹了關(guān)于Vue3指令之搜索框輸入防抖功能實現(xiàn)的相關(guān)資料,需要的朋友可以參考下

前言

「搜索??」這個場景在各種業(yè)務(wù)的系統(tǒng)中都是是非常常見的,比如電商平臺的商品搜索、百度搜索、掘金搜索、google搜索......,只要是有內(nèi)容呈現(xiàn)給用戶的,都少不了搜索功能。

按照觸發(fā)搜索動作的不同可分為:

  • 輸完關(guān)鍵字后手動觸發(fā)搜索
  • 輸入字符自動搜索

第一種是由用戶去決定何時進行搜索,沒啥問題。

第二種是通過監(jiān)聽用戶錄入的事件自動搜索,自動搜索能在一定程度上提升用戶體驗(比如在用戶輸入時關(guān)鍵詞聯(lián)想提示),同時也可能會帶來問題,因為input事件觸發(fā)是非常頻繁的,比如下面這個示例:

打開百度的搜索,找到輸入框的dom,然后綁定一個input事件,看看我們錄入一個telephone會觸發(fā)多少次input事件:

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

觸發(fā)了10次:

那如果每觸發(fā)一次都會調(diào)用后臺接口查詢,那當用戶量足夠大,就會給后臺服務(wù)器帶來很大的壓力,導(dǎo)致接口響應(yīng)慢,甚至引起服務(wù)器宕機,也會給用戶帶來不好的體驗。

為了不引起過多請求給服務(wù)端造成壓力,我們期望在用戶在輸入完以后再發(fā)起請求,那怎么判斷用戶是否輸入完了?

可以認為當用戶在一個固定的時間內(nèi)都沒有錄入字符是輸入完成/暫時輸入完成。這個是老生常談的知識點了————「防抖」和「節(jié)流」。掘金有很多文章專門寫這個的,筆者在此不過多描述,簡單一筆帶過說下筆者的看法。

防抖 & 節(jié)流

防抖

防抖的函數(shù)在調(diào)用后,如果在防抖時間內(nèi)沒有再次觸發(fā),就會在過了 防抖時間 后執(zhí)行;如果在防抖時間內(nèi)再次觸發(fā),不論觸發(fā)多少次,執(zhí)行的時機會一直往后延遲,直到滿足最后一次調(diào)用時間 小于 當前時間減去防抖時間才會執(zhí)行。

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

節(jié)流

節(jié)流函數(shù)在調(diào)用后,在設(shè)置的節(jié)流時間后執(zhí)行一次,在此期間,不論觸發(fā)多少次,都直接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)
  }
}

再來看下加了防抖 & 節(jié)流 處理的input事件執(zhí)行情況:

  • 防抖:

  • 防抖 + 節(jié)流:

從上面的兩個圖不難看出防抖 和節(jié)流的區(qū)別,節(jié)流的函數(shù)如果一直被觸發(fā),每隔一段時間執(zhí)行一次。而防抖則是一直延遲,最后執(zhí)行一次。

輸入防抖存在的問題

上面的防抖函數(shù)執(zhí)行貌似沒啥問題,前提是我們輸入的是英文,如果是中文輸入就出問題了,看下圖:

當中文輸入的時候,即使已經(jīng)防抖處理了,還可能會執(zhí)行多次。接下來咱們進入正題了,如何實現(xiàn)輸入防抖Vue3指令(并解決中文輸入觸發(fā)多次的問題)。

指令實現(xiàn)

為什么要以指令的方式實現(xiàn)?我能想到的有以下兩點:

  • 將防抖處理的邏輯封裝在指令內(nèi)部重用,更易用。
  • 指令要支持input輸入框,也要支持封裝input的組件,也就是說需要進行底層 DOM 訪問的邏輯,而這一點恰好是指令提供的能力之一。

需要補充Vue 指令相關(guān)知識的同學(xué)點這里自定義指令

期望使用方式:

<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>

即指令的綁定值為 執(zhí)行邏輯,指令參數(shù)為 防抖時長。

指令實現(xiàn):

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) // 執(zhí)行函數(shù)防抖處理
      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
    }
  }
}

接著處理中文輸入可能會觸發(fā)多次的問題??山柚?a rel="external nofollow" target="_blank">compositionstart和compositionend來實現(xiàn)。

  • 輸入法編輯器開始新的輸入合成時會觸發(fā) compositionstart 事件。例如,當用戶使用拼音輸入法開始輸入漢字時,這個事件就會被觸發(fā)。
  • 當文本段落的組成完成或取消時,compositionend 事件將被觸發(fā) (具有特殊字符的觸發(fā),需要一系列鍵和其他輸入,如語音識別或移動中的字詞建議)。

在一開始拼音輸入法時就設(shè)置composing為true,因此在compositionEnd沒有調(diào)用之前都不會執(zhí)行函數(shù),等compositionEnd調(diào)用,通過dispatchEvent派發(fā)一個input事件出去,保證邏輯一定會執(zhí)行。

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)
    }
  }
}

防抖實現(xiàn) & 判斷是 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('調(diào)用了onInput')
}
</script>

看下最終的效果:

差別還是非常明顯的。指令已發(fā)布npm倉庫,有需要可自取。

總結(jié)

??感謝瀏覽,通過本文你可以了解到以下內(nèi)容:

  • 防抖
  • 節(jié)流
  • Vue3指令開發(fā)
  • compositionstart 事件 (需要注意瀏覽器兼容性)
  • compositionend 事件(需要注意瀏覽器兼容性)

到此這篇關(guān)于Vue3指令之搜索框輸入防抖功能實現(xiàn)的文章就介紹到這了,更多相關(guān)Vue3搜索框輸入防抖內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Vue使用Element-UI實現(xiàn)分頁效果全過程

    Vue使用Element-UI實現(xiàn)分頁效果全過程

    element-ui官網(wǎng)上有分頁實現(xiàn)的功能,簡單方便又好用,也有很多分頁的樣式,你可以根據(jù)需要去選擇自己想要的樣式,下面這篇文章主要給大家介紹了關(guān)于Vue使用Element-UI實現(xiàn)分頁效果的相關(guān)資料,需要的朋友可以參考下
    2023-04-04
  • 詳解Vuex下Store的模塊化拆分實踐

    詳解Vuex下Store的模塊化拆分實踐

    這篇文章主要介紹了詳解Vuex下Store的模塊化拆分實踐,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-07-07
  • vue+element創(chuàng)建動態(tài)的form表單及動態(tài)生成表格的行和列

    vue+element創(chuàng)建動態(tài)的form表單及動態(tài)生成表格的行和列

    這篇文章主要介紹了vue+element創(chuàng)建動態(tài)的form表單及動態(tài)生成表格的行和列 ,本文通過實例代碼給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下
    2019-05-05
  • 記一次Vue中$route序列號報錯

    記一次Vue中$route序列號報錯

    本文主要介紹了記一次Vue中$route序列號報錯,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-04-04
  • vue+iview+less+echarts實戰(zhàn)項目總結(jié)

    vue+iview+less+echarts實戰(zhàn)項目總結(jié)

    本篇文章是作者通過學(xué)習(xí)vue+iview+less+echarts制作一個小系統(tǒng)后,做的心得以及遇到的坑的總結(jié),值得大家學(xué)習(xí)參考。
    2018-02-02
  • Vuex modules模式下mapState/mapMutations的操作實例

    Vuex modules模式下mapState/mapMutations的操作實例

    這篇文章主要介紹了Vuex modules 模式下 mapState/mapMutations 的操作實例,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-10-10
  • vue中使用ts配置的具體步驟

    vue中使用ts配置的具體步驟

    這篇文章主要介紹了vue中使用ts配置的具體步驟,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-08-08
  • Vue2?與?Vue3?的數(shù)據(jù)綁定原理及實現(xiàn)

    Vue2?與?Vue3?的數(shù)據(jù)綁定原理及實現(xiàn)

    這篇文章主要介紹了Vue2與Vue3的數(shù)據(jù)綁定原理及實現(xiàn),數(shù)據(jù)綁定是一種把用戶界面元素的屬性綁定到特定對象上面并使其同步的機制,使開發(fā)人員免于編寫同步視圖模型和視圖的邏輯
    2022-09-09
  • Vue實現(xiàn)動態(tài)圓環(huán)百分比進度條

    Vue實現(xiàn)動態(tài)圓環(huán)百分比進度條

    這篇文章主要為大家詳細介紹了Vue實現(xiàn)動態(tài)圓環(huán)百分比進度條,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • vue cli中env的使用指南

    vue cli中env的使用指南

    眾所周知,一個項目在開發(fā)、測試與生產(chǎn)環(huán)境的各種配置變量是不一樣的,但在vue cli 3中通過指令vue create xxx創(chuàng)建的項目取消了默認的 config 和 build 文件夾,這導(dǎo)致剛?cè)胧值男』锇椴恢涝谀膬号渲铆h(huán)境變量,不過官方也提供了相應(yīng)的配置方法,本文就來介紹一下
    2021-08-08

最新評論

湾仔区| 义马市| 务川| 成都市| 平塘县| 萍乡市| 大姚县| 岢岚县| 高安市| 常山县| 定南县| 类乌齐县| 文成县| 孟津县| 高雄县| 景谷| 龙陵县| 溧水县| 大荔县| 渑池县| 乌鲁木齐市| 青海省| 安陆市| 蒲江县| 仁化县| 玛曲县| 宁津县| 平南县| 鄂伦春自治旗| 改则县| 潮安县| 雅江县| 息烽县| 阳原县| 凭祥市| 桂阳县| 唐河县| 武山县| 成安县| 永康市| 波密县|