日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > vue >内容正文

vue

Vue组件实现函数防抖

發布時間:2025/6/17 vue 50 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Vue组件实现函数防抖 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

最近在掘金看到兩篇非常不錯的文章:

  • 以vue組件或者插件的形式,實現throttle或者debounce
  • 奇技淫巧 - Vue Mixins 高級組件 與 Vue HOC 高階組件 實踐

這兩篇文章中作者都分享了關于把函數防抖/函數節流包裝成通用組件的經驗。

在這里我就不介紹函數防抖/函數節流的概念了,將這樣的功能封裝是組件真的是非常實用。

通過HOC(高階組件)的方式進行封裝的思路我也很喜歡,這里也想分享一個類似的封裝方法

抽象組件

這里我使用了abstract: true來創建一個抽象組件。

我們常用的transition和keep-alive就是一個抽象組件。抽象組件是無狀態的,同樣也是“不存在的”,它自己并不會被渲染為實際的DOM,而是直接返回以及操作它的子元素。

例如對于模板(Debounce是一個抽象組件):

<Debounce><button>123</button> </Debounce> 復制代碼復制代碼

會被渲染成:

<button>123</button> 復制代碼復制代碼

實現

這里直接貼出組件代碼:

const debounce = (func, time, ctx) => {let timerconst rtn = (...params) => {clearTimeout(timer)timer = setTimeout(() => {func.apply(ctx, params)}, time)}return rtn }Vue.component('Debounce', {abstract: true,props: ['time', 'events'],created () {this.eventKeys = this.events.split(',')this.originMap = {}this.debouncedMap = {}},render() {const vnode = this.$slots.default[0]this.eventKeys.forEach((key) => {const target = vnode.data.on[key]if (target === this.originMap[key] && this.debouncedMap[key]) {vnode.data.on[key] = this.debouncedMap[key]} else if (target) {this.originMap[key] = targetthis.debouncedMap[key] = debounce(target, this.time, vnode)vnode.data.on[key] = this.debouncedMap[key]}})return vnode}, }) 復制代碼復制代碼

Debounce組件會接受time和events(用逗號分隔)的兩個參數。

在render函數中,Debounce組件修改了子VNode的事件,再將其返回回去。

使用

然后我們來使用一下:

<div id="app"><Debounce :time="1000" events="click"><button @click="onClick($event, 1)">click+1 {{val}}</button></Debounce><Debounce :time="1000" events="click"><button @click="onClick($event, 2)">click+2 {{val}}</button></Debounce><Debounce :time="1000" events="mouseup"><button @mouseup="onAdd">click+3 {{val}}</button></Debounce><Debounce :time="1000" events="click"><button @mouseup="onAdd">click+3 {{val}}</button></Debounce> </div> 復制代碼復制代碼const app = new Vue({el: '#app',data () {return {val: 0,}},methods: {onClick ($ev, val) {this.val += val},onAdd () {this.val += 3}} }) 復制代碼復制代碼

使用指令

使用自定義指令也是一種思路,不過指令的bind發生在created的回調中,也就是晚于事件的初始化的,這樣的話就不能通過修改vnode.data.on來改變綁定的事件回調,只能自己來綁定事件了:

Vue.directive('debounce', {bind (el, { value }, vnode) {const [target, time] = valueconst debounced = debounce(target, time, vnode)el.addEventListener('click', debounced)el._debounced = debounced},destroy (el) {el.removeEventListener('click', el._debounced)} }) 復制代碼復制代碼

這里要注意的一點是,指令binding.value的求值過程和事件綁定是不同的,并不支持onClick($event, 2)的寫法,因此如果這樣的綁定就只能再包一層了:

<button v-debounce="[($ev) => { onClick($ev, 4) }, 500]">click+4 {{val}}</button> 復制代碼復制代碼

小結

使用抽象組件的好處是提高了組件的通用性,不會因為組件的使用而污染DOM(添加并不想要的div標簽等)、可以包裹任意的單一子元素,當然也有缺點,比如使用時要注意子元素只能包含一個根,使用起來也比較啰嗦(參考文章中ButtonHoc在使用時更簡潔一些,但相應的是只能作為Button渲染)。


總結

以上是生活随笔為你收集整理的Vue组件实现函数防抖的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。