# vue-event-util
**Repository Path**: laden666666/vue-event-util
## Basic Information
- **Project Name**: vue-event-util
- **Description**: The util of Vue event. Provides extended functions such as throttling, debounce, delay
- **Primary Language**: JavaScript
- **License**: MIT
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2018-09-27
- **Last Updated**: 2020-12-19
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
vue-event-util
`vue-event-util`,是一个Vue事件的扩展插件,为Vue的事件提供了如**函数节流(throttle)**、**函数防抖(debounce)**、**函数延时(delay)** 等功能。`vue-event-util`将[lodash](https://lodash.com/ "") 的很多处理函数的工具函数加入到插件中,大家可用使用`vue-event-util`提供的便携方法将其应用到Vue的事件中。
## 源码
[github](https://github.com/laden666666/vue-event-util "") ,[码云](https://gitee.com/laden666666/vue-event-util "")
## 功能
* 0.对Vue的事件响应函数提供**函数防抖(throttle)**、**函数节流(debounce)**、**延时执行(delay)** 等函数处理功能
* 1.对某控件**所有实例**共享的函数进行函数防抖和函数节流
* 2.对某控件**各个实例**的函数进行函数防抖和函数节流
* 3.对**列表渲染的控件绑定的函数**进行函数防抖和函数节流
* 4.实现防止按钮连击
* 5.实现降低事件响应频率
* 6.实现延时事件响应
## 兼容性
Android | Firefox | Chrome | IE | iPhone | Edge | Safari
|
>=4.4 | √ | √ | >=9 | √ | √ | √ |
## 例子
防止按钮连击:[docs/ButtonSafe.html](https://laden666666.github.io/vue-event-util/ButtonSafe.html "") [源码](./docs/ButtonSafe.html "")
事件降频触发:[docs/FrequencyReduction.html](https://laden666666.github.io/vue-event-util/FrequencyReduction.html "") [源码](./docs/FrequencyReduction.html "")
事件延时触发:[docs/Delay.html](https://laden666666.github.io/vue-event-util/Delay.html "") [源码](./docs/Delay.html "")
## 插件解决的问题
当我们对函数进行**柯里化**、**函数节流**、**函数防抖**处理的时候,往往需要将原有函数以入参传入,并以返回函数的形式返回处理后的函数。如lodash库对函数防抖的实现:
```javascript
fn = _.throttle(fn, 1000)
```
但是这个处理对于Vue的template语法中的事件响应函数来说,实现起来很麻烦,我们以做**函数防抖**为例,看看我们以往在Vue中是如何实现上述操作的。Vue的事件绑定有两种方法:[方法名绑定](https://cn.vuejs.org/v2/guide/events.html#%E4%BA%8B%E4%BB%B6%E5%A4%84%E7%90%86%E6%96%B9%E6%B3%95 "") 和[内联处理器](https://cn.vuejs.org/v2/guide/events.html#%E5%86%85%E8%81%94%E5%A4%84%E7%90%86%E5%99%A8%E4%B8%AD%E7%9A%84%E6%96%B9%E6%B3%95 "") 。**内联处理器**允许我们提供一个表达式处理事件,但表达式没有**记忆功能**,因此无法实现如**函数节流**、**函数防抖**这样的功能。
```html
```
每一次点击都会执行一次_.throttle方法,所以上述代码是无法实现对事件的函数节流处理的。
另一种方法是先将函数进行处理,再通过方法名绑定或者内联处理器的方式绑定到Vue上面。
```html
```
这样写也存在一个问题,就是所有控件公用一个节流函数,当多个控件需要单独做函数节流的话就没有办法了。而且对于列表渲染,如果列表的每一个控件都要单独做函数节流处理,这样就更麻烦了。
有时候我们甚至会借助watch来实现函数节流的功能。如:
```html
```
方法是死的人是活的,我们肯定能找到更优雅的方式来做函数节流或者其他类似的事情。`vue-event-util`就是为了解决这个事情而生的。
## 安装
```javascript
npm install vue-event-util
```
然后在js中执行
```javascript
import vueEventUtil from 'vue-event-util'
import Vue from 'vue'
Vue.use(vueEventUtil)
```
在浏览器环境中,直接将**vue-event-util.js**文件引入即可。
```html
```
## 使用
`vue-event-util`提供了lodash的**delay**、**throttle**、**debounce**等方法
* delay: 延迟 wait 毫秒后调用 func
* debounce: 创建一个 debounced(防抖动)函数,该函数会从上一次被调用后,延迟 wait 毫秒后调用 func 方法。
* throttle: 创建一个节流函数,在 wait 秒内最多执行 func 一次的函数
三种函数具体用法可以参考[lodash](https://lodash.com/docs "") 。
#### 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`上提供的这些全局处理方法,具体用法如下:
```javascript
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函数里调用的方式,方法名绑定,如
```html
方法里面调用vue-event-util处理函数
内联处理器里调用vue-event-util处理函数
```
可以在方法里面调用vue-event-util函数:
```javascript
export default {
methods: {
method(parameter){
console.log(parameter)
},
throttle(parameter){
//将函数真正的处理逻传入vue-event-util的$throttle函数里,实现对函数节流的效果
this.$throttle((parameter)=>{
this.method(parameter)
}, 1000)(parameter)
},
}
}
```
也可以在内联处理器里调用vue-event-util处理函数:
```html
```
### 列表渲染函数
当出现列表循环的时候,如果希望每一个循环出的元素拥有自己的事件处理函数,可以给每个元素提供一个key,使得各个元素绑定的事件互不干扰,例:
```html
方法里面调用vue-event-util处理函数
内联处理器里调用vue-event-util处理函数
```
## 原理
`vue-event-util`是如何存对Vue绑定的函数实现**记忆**呢?
将每一个需要处理的函数toString,然后和其他参数(key,wait,option)一起做一个hash,最后用这个hash值做key将处理后的函数缓存起来。这是一个享元模式,如果hash已经存在就从缓存里面取,如果不存在就对函数进行处理,再缓存。因为如果一个函数的key、wait、option都相同,那这个函数的hash值也相同,所以就可以缓存这个函数了。