feat: 添加长按指令及使用示例,该长按指令支持自定义时长的持续回调 (#620)

This commit is contained in:
xiaoming 2023-06-23 11:17:39 +08:00 committed by GitHub
parent 5f71e0aad7
commit b8200125dc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 109 additions and 6 deletions

View File

@ -68,7 +68,7 @@ menus:
hsguide: Guide
hsAble: Able
hsMenuTree: Menu Tree
hsOptimize: Debounce、Throttle、Copy Directives
hsOptimize: Debounce、Throttle、Copy、Longpress Directives
hsWatermark: Water Mark
hsPrint: Print
hsDownload: Download

View File

@ -68,7 +68,7 @@ menus:
hsguide: 引导页
hsAble: 功能
hsMenuTree: 菜单树结构
hsOptimize: 防抖、截流、复制指令
hsOptimize: 防抖、截流、复制、长按指令
hsWatermark: 水印
hsPrint: 打印
hsDownload: 下载

View File

@ -1,5 +1,5 @@
import { hasAuth } from "@/router/utils";
import { Directive, type DirectiveBinding } from "vue";
import type { Directive, DirectiveBinding } from "vue";
export const auth: Directive = {
mounted(el: HTMLElement, binding: DirectiveBinding) {

View File

@ -1,7 +1,7 @@
import { message } from "@/utils/message";
import { useEventListener } from "@vueuse/core";
import { copyTextToClipboard } from "@pureadmin/utils";
import { Directive, type DirectiveBinding } from "vue";
import type { Directive, DirectiveBinding } from "vue";
interface CopyEl extends HTMLElement {
copyValue: string;

View File

@ -1,3 +1,4 @@
export * from "./auth";
export * from "./copy";
export * from "./longpress";
export * from "./optimize";

View File

@ -0,0 +1,63 @@
import { useEventListener } from "@vueuse/core";
import type { Directive, DirectiveBinding } from "vue";
import { subBefore, subAfter, isFunction } from "@pureadmin/utils";
export const longpress: Directive = {
mounted(el: HTMLElement, binding: DirectiveBinding) {
const cb = binding.value;
if (cb && isFunction(cb)) {
let timer = null;
let interTimer = null;
let num = 500;
let interNum = null;
const isInter = binding?.arg?.includes(":") ?? false;
if (isInter) {
num = Number(subBefore(binding.arg, ":"));
interNum = Number(subAfter(binding.arg, ":"));
} else if (binding.arg) {
num = Number(binding.arg);
}
const clear = () => {
if (timer) {
clearTimeout(timer);
timer = null;
}
if (interTimer) {
clearInterval(interTimer);
interTimer = null;
}
};
const onDownInter = (ev: PointerEvent) => {
ev.preventDefault();
if (interTimer === null) {
interTimer = setInterval(() => cb(), interNum);
}
};
const onDown = (ev: PointerEvent) => {
clear();
ev.preventDefault();
if (timer === null) {
timer = isInter
? setTimeout(() => {
cb();
onDownInter(ev);
}, num)
: setTimeout(() => cb(), num);
}
};
// Register using addEventListener on mounted, and removeEventListener automatically on unmounted
useEventListener(el, "pointerdown", onDown);
useEventListener(el, "pointerup", clear);
useEventListener(el, "pointerleave", clear);
} else {
throw new Error(
'[Directive: longpress]: need callback and callback must be a function! Like v-longpress="callback"'
);
}
}
};

View File

@ -6,7 +6,7 @@ import {
throttle
} from "@pureadmin/utils";
import { useEventListener } from "@vueuse/core";
import { Directive, type DirectiveBinding } from "vue";
import type { Directive, DirectiveBinding } from "vue";
/** 防抖v-optimize或v-optimize:debounce、节流v-optimize:throttle指令 */
export const optimize: Directive = {

View File

@ -13,6 +13,9 @@ const searchFour = ref("");
const searchFive = ref("");
const searchSix = ref("copy");
const text = ref("可复制的文本");
const long = ref(false);
const cbText = ref("");
const idx = ref(0);
function onInput() {
message(search.value);
@ -30,13 +33,30 @@ function onInputFour() {
function onInputFive({ name, sex }) {
message(`${name}${sex}${searchFive.value}`);
}
function onLongpress() {
long.value = true;
}
function onCustomLongpress() {
long.value = true;
}
function onCbLongpress() {
idx.value += 1;
long.value = true;
cbText.value = `持续回调${idx.value}`;
}
function onReset() {
long.value = false;
cbText.value = "";
idx.value = 0;
}
</script>
<template>
<el-card shadow="never">
<template #header>
<div class="card-header">
<span class="font-medium">自定义防抖截流文本复制指令</span>
<span class="font-medium">自定义防抖截流文本复制长按指令</span>
</div>
</template>
<div class="mb-2">
@ -113,5 +133,24 @@ function onInputFive({ name, sex }) {
文本复制指令自定义触发事件单击复制
<span v-copy:click="text" class="text-sky-500">{{ text }}</span>
</div>
<el-divider />
<el-space wrap>
长按指令
<el-button v-longpress="onLongpress">长按默认500ms</el-button>
<el-button v-longpress:1000="onCustomLongpress">
自定义长按时长1000ms
</el-button>
<el-button v-longpress:2000:200="onCbLongpress">
2秒后每200ms持续回调
</el-button>
<el-button @click="onReset"> 重置状态 </el-button>
<el-tag :type="long ? 'success' : 'info'" class="ml-2" size="large">
{{ long ? "当前为长按状态" : "当前非长按状态" }}
</el-tag>
<el-tag v-if="cbText" type="danger" class="ml-2" size="large">
{{ cbText }}
</el-tag>
</el-space>
</el-card>
</template>