el-table绑定的相同事件怎么去区分他们?
Merry He 6/14/2023
最近项目中有这么一个需求, 表格的操作栏的每一行中都有一个 '导出内容' 按钮 ,点击按钮导出对应通道的内容, 对于同一个导出按钮要求在30秒内不能重复触发导出事件, 30秒内重复点击给出提示。
通道ID | 通道名称 | 通道内容来源 | 操作 |
---|---|---|---|
00089 | 测试通道 | 新闻资讯 | 导出内容 |
00065 | 回归测试通道 | 环球新闻 | 导出内容 |
00066 | 开发阶段通道 | 人民日报 | 导出内容 |
对于这个需求, 想必大家第一时间就想到了节流
<el-button @click='exportChannelContent(scope.row.id)'>导出内容</el-button>
//导出内容
const exportChannelContent = throttle(handleExport, exportTip, 30 * 1000)
async function handleExport(channelId: string) {
const params = {id:channelId}
//调接口开始导出 do something.....
}
function exportTip() {
//提示
ElMessage({
message: '请勿短时内重复导出',
type: 'warning'
})
}
//节流( 时间戳、定时器皆可 )
export function throttle(fn: any,fn2:any, interval: number) {
let lastTime = 0
return function (this: any, ...args: any[]) {
// 获取当前时间戳
const nowTime = new Date().getTime()
// cd剩余时间
const remainTime = nowTime - lastTime
// 节流时间间隔外
if (remainTime - interval >= 0) {
//执行传入的导出事件
fn.apply(this, args)
// 将上一次函数执行的时间设置为触发事件时的时间
lastTime = nowTime
} else {
//delay时间间隔内重复触发事件提示
fn2()
}
}
}
写好了, 测试一手.....发现,点击 00089通道对应的'导出内容'按钮后, 30秒内再点击00065通道对应的'导出内容'按钮, 00065通道没有像00089通道一样导出内容,而是提示'请勿短时内重复导出'。
问题 : 其实就是点击每一个 '导出内容'按钮都触发了同一个事件,在30秒内再次触发事件当然就会走进节流函数的 else 的提示里
解决 : 最先想到的是用元素的索引来区分每行的 导出内容按钮,在这个地方使用索引作为判断依据有个缺陷,这个地方的 el-table是带分页功能的,假如点了第一页的第一个,然后在30秒内切换到第二页点击第一个还是会走进else里给出提示,因为他们的索引是相同的,都是0。这时候通道ID就派上用场了,可以把它作为唯一性的判断依据,对上面的节流函数做一下调整。
//节流
export function throttle(fn: any,fn2:any, interval: number) {
let lastTime = 0
let channelId = '' //点击导出时-用于区分不同的通道对应的按钮
return function (this: any, ...args: any[]) {
// 获取当前时间
const nowTime = new Date().getTime()
// cd剩余时间
const remainTime = nowTime - lastTime
// 节流时间间隔外 或者 点击了其他通道的导出皆可触发导出
if (remainTime - interval >= 0 || channelId !== args[0]) {
fn.apply(this, args)
//将上一次导出时对应的通道ID存在内存中
channelId = args[0]
// 将上一次函数执行的时间设置为触发事件时的时间
lastTime = nowTime
} else {
//delay时间间隔内重复触发事件提示
fn2()
}
}
}
handleExport 函数传入的 channelId 作为内部闭包函数访问到的外部变量会存储在内存当中,每次触发事件都会去校验点击的是不是上一次的通道ID对应的 '导出内容'按钮, 这样这个需求就搞定了。