vue-event-util
v0.0.2
Published
The util of Vue event. Provides extended functions such as throttling, debounce, delay.
Downloads
6
Maintainers
Readme
vue-event-util
,是一个Vue事件的扩展插件,为Vue的事件提供了如函数节流(throttle)、函数防抖(debounce)、函数延时(delay) 等功能。vue-event-util
将lodash 的很多处理函数的工具函数加入到插件中,大家可用使用vue-event-util
提供的便携方法将其应用到Vue的事件中。
源码
功能
- 0.对Vue的事件响应函数提供函数防抖(throttle)、函数节流(debounce)、延时执行(delay) 等函数处理功能
- 1.对某控件所有实例共享的函数进行函数防抖和函数节流
- 2.对某控件各个实例的函数进行函数防抖和函数节流
- 3.对列表渲染的控件绑定的函数进行函数防抖和函数节流
- 4.实现防止按钮连击
- 5.实现降低事件响应频率
- 6.实现延时事件响应
兼容性
例子
防止按钮连击:docs/ButtonSafe.html 源码
事件降频触发:docs/FrequencyReduction.html 源码
事件延时触发:[docs/Delay.html源码 ](https://laden666666.github.io/vue-event-util/Delay.html "")
插件解决的问题
当我们对函数进行柯里化、函数节流、函数防抖处理的时候,往往需要将原有函数以入参传入,并以返回函数的形式返回处理后的函数。如lodash库对函数防抖的实现:
fn = _.throttle(fn, 1000)
但是这个处理对于Vue的template语法中的事件响应函数来说,实现起来很麻烦,我们以做函数防抖为例,看看我们以往在Vue中是如何实现上述操作的。Vue的事件绑定有两种方法:方法名绑定 和内联处理器 。内联处理器允许我们提供一个表达式处理事件,但表达式没有记忆功能,因此无法实现如函数节流、函数防抖这样的功能。
<template>
<button @clikc="_.throttle(fn, 1000)()">函数节流</button>
</template>
每一次点击都会执行一次_.throttle方法,所以上述代码是无法实现对事件的函数节流处理的。
另一种方法是先将函数进行处理,再通过方法名绑定或者内联处理器的方式绑定到Vue上面。
<template>
<button @clikc="fn">函数节流</button>
</template>
<script>
export deflaut {
methods: {
fn: _.throttle(function(){
...
}, 1000)
},
}
</script>
这样写也存在一个问题,就是所有控件公用一个节流函数,当多个控件需要单独做函数节流的话就没有办法了。而且对于列表渲染,如果列表的每一个控件都要单独做函数节流处理,这样就更麻烦了。
有时候我们甚至会借助watch来实现函数节流的功能。如:
<template>
<button @clikc="fn">函数节流</button>
</template>
<script>
export deflaut {
created() {
this.$watch('clickTime', _.throttle(() => {
...
}, 200))
}
data: {
clickTime: 0,
}
methods: {
fn: function(){
this.clickTime++
}
},
}
</script>
方法是死的人是活的,我们肯定能找到更优雅的方式来做函数节流或者其他类似的事情。vue-event-util
就是为了解决这个事情而生的。
安装
npm install vue-event-util
然后在js中执行
import vueEventUtil from 'vue-event-util'
import Vue from 'vue'
Vue.use(vueEventUtil)
在浏览器环境中,直接将vue-event-util.js文件引入即可。
<script src="vue-event-util.js"></script>
<script>
Vue.use(vueEventUtil)
</script>
使用
vue-event-util
提供了lodash的delay、throttle、debounce等方法
- delay: 延迟 wait 毫秒后调用 func
- debounce: 创建一个 debounced(防抖动)函数,该函数会从上一次被调用后,延迟 wait 毫秒后调用 func 方法。
- throttle: 创建一个节流函数,在 wait 秒内最多执行 func 一次的函数
三种函数具体用法可以参考lodash 。
delay
延迟 wait 毫秒后调用 callback
参数
|参数名|参数类型|参数说明| |-|-|-| |callback|Function|延迟执行的函数| |wait|number|延迟的时间,单位毫秒|
返回值
|参数类型|参数说明| |-|-| |Function|处理后的函数|
debounce
创建一个 debounce(防抖动)函数,该函数会从上一次被调用后,延迟 wait 毫秒后调用 callback 方法。
参数
|参数名|参数类型|参数说明| |-|-|-| |callback|Function|需要做防抖函数| |wait|number|延迟的时间,单位毫秒| |options|object|选项对象| |options.leading|boolean|指定调用在延迟开始前,默认false| |options.maxWait|number|设置 func 允许被延迟的最大值| |options.trailing|boolean|指定调用在延迟结束后,默认true|
返回值
|参数类型|参数说明| |-|-| |Function|处理后的函数|
throttle
创建一个节流函数,在 wait 秒内最多执行 callback 一次的函数
参数
|参数名|参数类型|参数说明| |-|-|-| |callback|Function|需要做节流函数| |wait|number|节流时间,单位毫秒| |options|object|选项对象| |options.leading|boolean|指定调用在节流开始前,默认true| |options.trailing|boolean|指定调用在节流结束后,默认false(与lodash默认配置不同,主要是因为事件处理更常用trailing为false的情况,如防止按钮连击)|
返回值
|参数类型|参数说明| |-|-| |Function|处理后的函数|
这些方法可以通过3种方式对Vue控件的函数进行处理:
- 1.全局函数
- 2.控件实例函数
- 3.列表渲染函数
全局函数
vue-event-util
提供某控件所有实例共享的函数进行上述函数处理,这种使用方法,相当于作用于控件原型上的函数,一旦方法进行了处理后,控件的每一个实例会共享处理后的方法。通过vue-event-util
上提供的这些全局处理方法,具体用法如下:
import eventUtil from 'vue-event-util'
export deflaut {
methods: {
delay: eventUtil.delay(function(argument){
...
}, 100),
throttle: eventUtil.throttle(function(argument){
...
}, 100),
debounce: eventUtil.debounce(function(argument){
...
}, 100),
}
}
控件实例函数
vue-event-util
在Vue实例的原型上提供了上述函数处理,使用原型上的方法去处理函数,处理后的结果是控件实例独享的,针对Vue事件绑定函数的方法不同,vue-event-util
提供两种不同的方法:
可以在方法里面使用$xxx函数里调用的方式,方法名绑定,如
<template>
<div class="test">
<p>方法里面调用vue-event-util处理函数</P>
<button @click="delay(count)" >delay2</button>
<button @click="throttle(count)" >throttle2</button>
<button @click="debounce(count)" >debounce2</button>
<p>内联处理器里调用vue-event-util处理函数</P>
<button @click="$delay(method, 1000)('delay')" >delay</button>
<button @click="$throttle(method, 1000)('throttle')" >throttle</button>
<button @click="$debounce(method, 1000)('debounce')" >debounce</button>
</div>
</template>
<script>
export default {
methods: {
method(parameter){
console.log(parameter)
},
//方法里面调用vue-event-util的delay函数
delay(parameter){
this.$delay((parameter)=>{
this.method(parameter)
}, 1000)(parameter)
},
//方法里面调用vue-event-util的throttle函数
throttle(parameter){
this.$throttle((parameter)=>{
this.method(parameter)
}, 1000)(parameter)
},
//方法里面调用vue-event-util的debounce函数
debounce(parameter){
this.$debounce((parameter)=>{
this.method(parameter)
}, 1000)(parameter)
},
},
}
</script>
可以在方法里面调用vue-event-util函数:
export default {
methods: {
method(parameter){
console.log(parameter)
},
throttle(parameter){
//将函数真正的处理逻传入vue-event-util的$throttle函数里,实现对函数节流的效果
this.$throttle((parameter)=>{
this.method(parameter)
}, 1000)(parameter)
},
}
}
</script>
也可以在内联处理器里调用vue-event-util处理函数:
<template>
<div class="test">
<button @click="$throttle(method, 1000)('throttle')" >throttle</button>
</div>
</template>
<script>
export default {
methods: {
method(parameter){
console.log(parameter)
},
},
}
</script>
列表渲染函数
当出现列表循环的时候,如果希望每一个循环出的元素拥有自己的事件处理函数,可以给每个元素提供一个key,使得各个元素绑定的事件互不干扰,例:
<template>
<div class="test">
<p>方法里面调用vue-event-util处理函数</P>
<button v-for="key in 5" :key="key" @click="delay(key, count)" >delay2</button>
<button v-for="key in 5" :key="key" @click="throttle(key, count)" >throttle2</button>
<button v-for="key in 5" :key="key" @click="debounce(key, count)" >debounce2</button>
<p>内联处理器里调用vue-event-util处理函数</P>
<button v-for="key in 5" :key="key" @click="$delay(key, method, 1000)('delay')" >delay</button>
<button v-for="key in 5" :key="key" @click="$throttle(key, method, 1000)('throttle')" >throttle</button>
<button v-for="key in 5" :key="key" @click="$debounce(key, method, 1000)('debounce')" >debounce</button>
</div>
</template>
<script>
export default {
methods: {
method(parameter){
console.log(parameter)
},
//方法里面调用vue-event-util的delay函数
delay(key, parameter){
this.$delay(key, (parameter)=>{
this.method(parameter)
}, 1000)(parameter)
},
//方法里面调用vue-event-util的throttle函数
throttle(key, parameter){
this.$throttle(key, (parameter)=>{
this.method(parameter)
}, 1000)(parameter)
},
//方法里面调用vue-event-util的debounce函数
debounce(key, parameter){
this.$debounce(key, (parameter)=>{
this.method(parameter)
}, 1000)(parameter)
},
},
}
</script>
原理
vue-event-util
是如何存对Vue绑定的函数实现记忆呢?
将每一个需要处理的函数toString,然后和其他参数(key,wait,option)一起做一个hash,最后用这个hash值做key将处理后的函数缓存起来。这是一个享元模式,如果hash已经存在就从缓存里面取,如果不存在就对函数进行处理,再缓存。因为如果一个函数的key、wait、option都相同,那这个函数的hash值也相同,所以就可以缓存这个函数了。