vue-async-click
source link: https://dreambo8563.github.io/2022/03/31/vue-async-click/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
vue-async-click
Posted on 2022-03-31
| In vue
解决的问题
我们经常遇到
点击
按钮来触发某个异步
请求的情况, 比如 提交/确定 等按钮.
但这种情况我们又需要处理一些并发的问题, 防止用户连续频繁的触发异步
其他方案 (只列举几个)
自己设置一个标志位, 来标识是否在请求中, 每次触发后对标志位判断
缺点是需要额外设置标志位字段,重复性代码.降低代码可读性
对点击触发的异步 进行 throttle 处理
throttle设置的时间间隔是固定的, 没法估计请求实际使用的时间, 太短还是会连续触发. 太长体验很差
我的方案 async-click 指令
- vue2:
Vue.directive("async-click", { |
- vue3
app.directive("async-click", {
// 当被绑定的元素插入到 DOM 中时……
created(el, binding) {
// 获取 bind 的异步方案名称
console.debug(binding);
// const fnName = binding;
// 获取具体方法的引用
const fn = binding.value
if (!fn) {
console.error("async-click 指令需要 binding 一个方法");
}
// 设置内部的标志位
let start = false;
el.addEventListener(
"click",
(e: MouseEvent) => {
// 对其他 click 时间阻止
e && e.stopImmediatePropagation();
if (!start) {
// 第一次点
console.debug("click flag ->", start);
start = true;
// 执行,并获得返回值
const rt: Promise<unknown> = fn();
if (!(rt instanceof Promise)) {
console.error("async-click 指令绑定值错误:返回类型必须为 Promise");
}
console.debug(rt);
//! 此处需要特别注意, 必须是 Promise 完成, 不能再某种情况下永远处于 pending 状态
rt.finally(() => {
// promise 结束后重置标志位
console.debug("finally");
start = false;
});
}
},
true
);
}
});
使用侧例子:
`将原来 @click=xxx 的部分替换为 v-async-click=xxx
<van-button |
methods:{ |
未来可扩展部分:
- 针对不同的事件
- 可以带入参数 fn(arg)
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK