vue之放抖动与节流
模拟需求:在input输入框中输入账号,求情接口,返回所有账号中包含的数据,不需要点击按钮
我们大概看一下原型图
需求分析
1、没有button,那么我们需要监听文本框的输入时间,判断值改变后去请求后台,将数据返回显示。
2、文本框清空后数据清零。
没错,大概就这两个,而且基本上没有难度。
老样子,先把基础的代码写好,如同那些下象棋的人一样,开始几步的套路都是一样的,不用思考。
<!-- html代码 --> <el-input placeholder="搜索" v-model="undefined" clearable size="mini"> <i slot="prefix" class="el-input__icon el-icon-search"></i> </el-input> <ul> <li v-for="item in resultList"> <!-- 具体显示效果... --> </li> </ul> <!-- js代码 --> <script> var app; var vm = new Vue({ el: '#app', data: function () { app = this; return { search: undefined, //搜索值 resultList:[] //返回结果 } }, mounted: { } }); </script>
ok,基本的已经完成了,既然是请求数据,那么肯定有一个请求接口的方法
mounted: { getData() { axios.post(url,{ 参数1:值1, ... }).then(function (response) { //符合你结构的判断,我这里简单处理,直接赋值 app.resultList= response.data.data; }).catch(function (error) { console.log(error); }); } }
那么现在第一个问题来了,我该怎么去调用这个方法,没有按钮可以点击,如何出发事件?既然用的vue,那么vue中的侦听器侦听器大家或许用过,
那就是:watch,具体的理论知识我就不说了,可以去看文档(其实我也不清楚)。
var vm = new Vue({ el: '#app', data: function () { app = this; return { search: undefined, //搜索值 resultList:[] //返回结果 } }, mounted: { getData() { axios.post(url,{ 参数1:值1, ... }).then(function (response) { //符合你结构的判断,我这里简单处理,直接赋值 app.resultList= response.data.data; }).catch(function (error) { console.log(error); }); } }, watch: { 'search': function (value) { if (!value) { //当值为空时 app.resultList=[]; } else { //请求接口,这里的app 是之前定义的,至于为什么要这样定义,是因为存在js闭包问题 app.getData(); //检查请求次数 console.log('请求后台') }; } } });
好,搞了半天似乎和标题并没有任何关系。。。
下面进入正题,我们先看下这样写行不行。
可以看到,当我输入“17608”的时候,其实是求情了5次的,这么频繁的请求不说大家也懂,资源浪费嘛,试想一下,当数据量非常大的时候,这样写的话,嘿嘿嘿
好,然后你去和产品经理沟通,说了一推资源浪费等等的话,完全不鸟你,我就要这个亚子...(脑补中)
办法总比困难多,我们可以想一下在用户输入完条件后再去查找,在这个值没有变化的时候我们就可以去请求了。
watch: { 'search': function (value) { if (!value) { //当值为空时 app.resultList=[];se } else { setTimeout(() => { app.getData(); console.log('请求后台') }, 1000); }; } }
这样一看就不行,都不用运行,结果和上面并没有什么区别,我也就不分析了,我们来修改一下
'search': function (value) { let timeout; //当值变化的时候清除定时器 clearTimeout(timeout); if (!value) { //当值为空时 app.resultList=[]; } else { timeout= setTimeout(() => { app.getData(); console.log('请求后台') }, 1000); }; }
没错,只要侦听到值在变化,我就把上一次的清除掉,想法是对的,但是还有问题,timeout的作用域问题,每进来一次,就会重新申明一次,所以你根本就清除不了。
el:'#app', data: function(){ app = this; return { search: undefined, //搜索值 resultList: [], //返回结果 timeout: undefined //防抖动 定时器变量 } },
我们在这里定义,每次作用到的都是一个变量上
'search': function (value) { //当值变化的时候清除定时器 clearTimeout(app.timeout); if (!value) { //当值为空时 app.resultList=[]; } else { app.timeout= setTimeout(() => { app.getData(); console.log('请求后台') }, 1000); }; }
ok,这样就完成了,先清除上一次的,在去重新请求。你要是问我怎么就知道要把之间间隔设成一秒,万一我就要两秒输入一个字符呢,大哥,要不要让你的手机壳
跟着你的心情变色啊
这个是就防抖动,节流与这个在我看来大同小异,他是根据时间的变化来判断,用户在多少多少秒之内输入去请求一次,聪明的人一说就懂。
代码格式不晓得咋回事,突然就乱了,我也懒得调了。。。。
最后放一波效果图