节流(时间戳):一个函数执行一次后,只有大于设定的时间,才会执行第二次。
//防抖
// triggerNow 是否立即触发
function debounce(fn, time, triggerNow) {
var t = null
var debounced = function() {
var _self = this,
args = arguments;
if (t) {
clearTimeout(t)
}
if (triggerNow) {
var exec = !t
t = setTimeout(function() {
t = null
}, time)
if (exec) {
fn.apply(_self, args)
} else {
t = setTimeout(function() {
fn.apply(_self, args)
}, time)
}
}
}
debounced.remove = function() {
clearTimeout(t)
t = null
}
return debounced
}
防抖(定时器):频繁的触发函数,在规定的时间最后一次生效前面的不生效。(延迟执行)
//节流
function throttle(fn, delay) {
var t = null,
begin = new Date().getTime()
return function() {
var _self = this,
args = arguments,
cur = new Date().getTime();
clearTimeout(t);
if (cur - begin >= delay) {
fn.apply(_self, args)
begin = cur
} else {
t = setTimeout(function() {
fn.apply(_self, args)
}, delay)
}
}
}
vue3自定义
image.png
应用场景
防抖(debounce)
search搜索,用户在不断输入值时,用防抖来节约请求资源
。window触发resize的时候,不断的调整浏览器窗口大小会不断的触发这个事件,用防抖来让其只触发一次
节流(throttle)
鼠标不断点击触发,mousedown(单位时间内只触发一次)
监听滚动事件,比如是否滑到底部自动加载更多,用throttle来判断
按钮只能点击一次的做法
为了防止用户连续点击一个按钮而导致代码处理错乱,可参考以下代码为按钮上锁:
var feedbtnlock = 0;
if (feedbtnlock == 0) {
feedbtnlock = 1;
setTimeout(function(){
feedbtnlock = 0;
}, 1500);
} else {
ui.error('请勿重复点击按钮!');
return false;
}
feedbtnlock初始值为0,点击按钮后,将值设置为1,在1.5秒之后值会恢复为0,如果1.5秒之内
再次点击按钮,则会执行else语句块里面的代码 return false.
自定义指令
一、新建plugins.js
import Vue from 'vue'
// 在vue上挂载一个指量 preventReClick
const preventReClick = Vue.directive('preventReClick', {
inserted: function (el, binding) {
console.log(el.disabled)
el.addEventListener('click', () => {
if (!el.disabled) {
el.disabled = true
setTimeout(() => {
el.disabled = false
}, binding.value || 3000)
//binding.value可以自行设置。如果设置了则跟着设置的时间走
//例如:v-preventReClick='500'
}
})
}
});
export { preventReClick }
二、在main.js中引入
import preventReClick from './utils/plugins.js'
三、设置button重复点击
<Button v-if="isVerificate" type="primary" @click="getCode" v-preventReClick>获取验证码</Button>
防抖与节流
在前端开发的过程中,我们经常会需要绑定一些持续触发的事件,如 resize、scroll、mousemove 等等,但有些时候我们并不希望在事件持续触发的过程中那么频繁地去执行函数。这时候就用到防抖与节流。微信搜索公众号:Java项目精选,回复:java 领取资料 。
案例 1:远程搜索时需要通过接口动态的获取数据,若是每次用户输入都接口请求,是浪费带宽和性能的。
<Select :remote-method="remoteMethod">
<Option v-for="item in temoteList" :value="item.value" :key="item.id">{{item.label}}</Option>
</Select>
<script>
function debounce(fn, wait) {
let timeout = null
return function () {
if (timeout !== null) clearTimeout(timeout)
timeout = setTimeout(fn, wait)
}
}
export default {
methods:{
remoteMethod:debounce(function (query) {
// to do ...
}, 200),
}
}
<script>
案例 2:持续触发 scroll 事件时,并不立即执行 handle 函数,当 1000 毫秒内没有触发 scroll 事件时,才会延时触发一次 handle 函数。
function debounce(fn, wait) {
let timeout = null
return function () {
if (timeout !== null) clearTimeout(timeout)
timeout = setTimeout(fn, wait)
}
}
function handle() {
console.log(Math.random())
}
window.addEventListener('scroll', debounce(handle, 1000))