上一篇博文我们讲到了节流函数的应用场景, 我们知道了节流函数可以用在模糊查询, scroller,onresize 等场景; 今天这篇我们来讲防抖函数的应用场景::
通过上一篇博文的学习, 我们知道了防抖函数的原理: 只有在事件触发的时候才会延迟加载, 如果在延迟加载之前再次触发, 则会刷新延迟时间重新延迟, 触发次数有且只有触发一次;
如果对防抖函数原理有疑惑, 请点击链接跳转到关于防抖函数讲解的博文: https://www.cnblogs.com/dengyao-blogs/p/11436228.html
防抖函数一般是用于频繁触发事件, 而我们只需要它触发一次的场景, 比如: 输入框的 oninput 事件, button 按钮点击事件, 点赞等操作场景;
今天我们讲的 demo 场景是防抖函数实现手机号码校验:
HTML 视图层代码:
- <div id="app">
- <input type="text" placeholder="请输入手机号码" v-model="val" @keyup="check"/>
- <div class="box" v-show="statu==true"> 您输入的手机号码格式正确 </div>
- </div>
首先我们视图层代码是一个输入框后面加上一个 div 作为提示信息, HTML 代码很简单就不过多讲解了;
JS 数据逻辑层代码:
- // 这里我们要引入一个文件, 文件里面是防抖函数的是实现
- <script src="test.js"></script>
- <script>
- // 实例化 vue 对象
- new Vue({
- el:"#app",
- data:{
- //val 是双向数据绑定绑定输入框的值
- val:"",
- // 此处状态值是根据状态值的变化来修改后面 div 的提示信息
- statu:false
- },
- mounted(){
- },
- methods:{
- //check 是我们绑定的输入框的 @keyup 事件, 注意这里不能是函数, 不然不会触发, 必须要是对象
- check:debounce(function(){
- // 这里是我们调用方法, 也就是我们要做的事情
- this.handle();
- console.log(new Date())
- }),
- handle(){
- // 此处输入是为了统计 handle 事件触发的次数
- console.log("函数防抖");
- // 这里定义校验规则
- let reg = /^1[3|4|5|7|8][0-9]{9}$/;
- // 校验手机号规则
- // 如果校验不通过会返回 false, 如果校验通过会返回 true
- if(reg.test(this.val)){
- // 修改状态值方便上面的视图层判断展示
- this.statu=true;
- // 动态的修改提示信息
- document.getElementsByClassName("box").innerHTML="您输入的手机号码格式错误";
- }else{
- this.statu=false;
- document.getElementsByClassName("box").innerHTML="您输入的手机号码格式错误";
- }
- },
- }
- })
test.JS
- function debounce(fn) { // 默认 300 毫秒
- var timer;
- return function() {
- if(timer) {
- clearTimeout(timer);
- }
- timer = setTimeout(() => {
定时器必须要更改 this 指向, 可以用 apply,bind, 或者上面用变量转换等方式来进行更改 this 指向
- fn.apply(this); // this 指向 vue
- }, 1000);
- };
- }
最后, 我们的效果图如下 (这里只是简单的模拟效果, 视图层搭建的不是很美观):
image
我们可以看到我们打印的结果只输出了一次, 如果不使用防抖函数, 这里是会触发 11 次的, 因为一共输入了 11 个字符; 假设我们的方法体中是发送 Ajax 和操作 DOM 呢? 为了一个手机号码校验, 难道我们要进行 11 次甚至更多次的 Ajax 请求或者 DOM 操作吗? 如果是那样, 我们的程序性能可想而知, 所以说防抖函数是一种性能提升方案;
上述讲述的是我们之前常见的 cdn 方式引入 vue, 那么我们如何在 vue-cli 脚手架中使用防抖函数来进行提升性能呢?
vue-cli:
首先我们可以在 build 文件夹中新建一个 JS 文件, 这里我们定义 common.JS:
common.JS
- // 函数防抖
- export function debounce(fn, delay) {
- // 记录上一次的延时器
- var timer = null;
- var delay = delay || 200;
- return function() {
- // var args = arguments;
- var that = this;
- // 清除上一次延时器
- clearTimeout(timer)
- timer = setTimeout(function() {
- fn.apply(that)
- }, delay);
- }
- }
注意: 我们在 vue-cli 中自定义方法必须要 export 抛出, 不然组件读取不到
然后我们到我们需要用的文件中来进行引入和使用:
需要使用的组件:
import {debounce} from "../../build/common"
有抛出就一定有引入, 我们这里用 import 来引用 common.JS 文件里面的方法, 这里的 debounce 就是我们用来接收 common.JS 里面方法的变量;
调用方式跟上面的一样:
这里的 search 是视图层绑定的触发事件, 注意这里也需要是对象的形式来调用
- methods:{
- Search:debounce(function(){console.log(1234);},1000),
- }
总结:
1, 防抖函数和节流函数均属于一种性能优化方案, 有效的使用可以提升程序性能, 提升用户体验;
2, 防抖函数可适用于点赞, 输入框校验, 取消点赞, 创建订单等不可让用户同一时间内频繁进行操作的场景;
来源: http://www.jianshu.com/p/f55343d0bb0f