vue3+ts登入按钮防抖和节流

1.在uilt文件夹下新建一个DebounceThrottle.ts进行函数的封装

// 防抖:防抖指的是在事件触发n秒后再执行回调,如果在n秒内再次被触发,则重新计算时间。
// 为什么需要防抖:就拿用户登录来说,如果不做防抖操作,多次点击登入按钮就会多次请求后台,
// 既会造成不必要的性能消耗也会造成用户体验的不好
// 防抖在连续的事件,只需触发一次回调的场景有:
// 搜索框搜索输入。只需用户最后一次输入完,再发送请求。
// 窗口大小的改变resize。只需窗口调整完成后,计算窗口大小。防止重复渲染。
// 登录、发短信等按钮避免用户点击太快,以致于发送了多次请求,需要防抖。
// 实现过程:封装一个函数并传递两个参数,
// 第一个参数是需要调用的函数或者请求,第二个参数是延迟多少毫秒才执行函数
// 在函数里先定义一个空变量,再return一个匿名函数,在该函数中先判断定义的变量是否为空,
// 为空就添加一个定时器,不为空就清除定时器
// fn代表有个函数,里面可能会频繁发生回调或ajax
// delay表示间隔多少毫秒才触发,默认200毫秒
export function debounce(fn:Function,delay=200){//fn是需要防抖的函数,delay是延迟多少毫秒执行fn
    let timer:NodeJS.Timeout | null = null;
    return function (){
        if(timer){
            clearTimeout(timer);
        }
        timer=setTimeout(()=>{
            fn.apply(fn,arguments);
            timer = null;
        },delay)
        console.log(timer,"timer");
        
    }
}


// 节流:节流是指如果持续触发某个事件,则每隔n秒执行一次
// fn代表可能会频繁发生回调或ajax请求的函数
// delay表示间隔多少毫秒才触发,默认100毫秒
// 节流在间隔一段时间执行一次回调的场景有:
// 滚动加载,加载更多或滚到底部监听
// 搜索框,搜索联想功能
// 实现过程:封装一个函数并传递两个参数,
// 第一个参数是需要调用的函数或者请求,第二个参数是延迟多少毫秒才执行函数
// 在函数里先定义一个空变量,再return一个匿名函数,在该函数中先判断定义的变量是否为空,
// 为空就执行定时器,不为空就不执行定时器而不是像防抖一样清除定时器
export function throttle(fn:Function,delay=100){
    //首先设定一个变量,在没有执行我们的定时器为null
    let timer:NodeJS.Timeout|null = null;
    return function (){
        //当我们发现这个定时器存在时,则表示定时器已经在运行中,需要返回
        if(timer) return;
        timer =setTimeout(()=>{
            fn.apply(fn,arguments);
            timer = null;
        },delay)
    }
}

2.在需要做防抖和节流的组件中先引入封装的函数来进行使用(这里拿登入按钮防抖来举例)

//这个登入按钮传参会报红,但不会影响效果
<template>
<!-- 此处省略一万条代码 -->
<el-button class="btn-login" type="primary" @click="submitForm(ruleFormRef)">登 录</el-button>
</template>
<script lang="ts" setup>
import {debounce} from '@/util/DebounceThrottle'
const login = (formEl: FormInstance | undefined) => {//登入请求,传参做了验证
    if (!formEl) return
    formEl.validate((valid: any) => {
        if (valid) {
            const data = { ...ruleForm, _gp: "admin", _mt: "login" }//转换成字符串
            post(data).then(res => {
                let { data: token, errmsg, errno } = res as any;//获取登录状态
                if (200 == errno) {//登录成功的判断
                    ElMessage.success("登录成功!")//消息提示登录成功
                    let now = new Date();//获取当前时间
                    now.setTime(now.getTime() + 1000 * 60 * 30);//转成时间类型
                    Cookies.set("token", res.data, { expires: now })//获取token存到cookie
                    Object.assign(store.loginInfo,ruleForm)//将账号密码存储到状态管理
                    return Promise.resolve(token)
                } else {
                    ElMessage.error(errmsg);//登入失败
                    return Promise.reject(errmsg)
                }
            }).then(res => {
                const data = {
                    _gp: "admin",
                    _mt: "info"
                }
                post(data).then(res => {
                    const { data, errno, errmsg } = res as any
                    if (200 == errno) {
                        store.setUser(data)//调用状态管理中的方法
                        let back = route.query.back//获取路径
                        if (back) {
                            router.replace(<string>back);//断言
                            return
                        }
                        router.replace("/");
                    } else {
                        return Promise.reject(errmsg)
                    }
                })
            }).catch(err => {
                ElMessage.error(err)
            })
        } else {
            return false
        }
    })
}
let submitForm =debounce(login,800)//submitForm是点击事件,login是需要执行的回调函数
</script>
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值