vue3 + ts 自定义指令 防抖指令,节流指令,复制指令
-
本文使用了
element-ui ,
element-plus 官网 -
源文件
https://admin.spicyboy.cn/#/directives/debounceDirect
-
新建
copy.ts
文件 (复制指令)
import type { Directive, DirectiveBinding } from "vue";
import { ElMessage } from "element-plus";
interface ElType extends HTMLElement {copyData: string | number;__handleClick__: any;
}
const copy: Directive = {mounted(el: ElType, binding: DirectiveBinding) {el.copyData = binding.value;el.addEventListener("click", handleClick);},updated(el: ElType, binding: DirectiveBinding) {el.copyData = binding.value;},beforeUnmount(el: ElType) {el.removeEventListener("click", el.__handleClick__);}
};async function handleClick(this: any) {try {await navigator.clipboard.writeText(this.copyData);} catch (err) {console.error('复制失败');}ElMessage({type: "success",message: "复制成功"});
}export default copy;
- 新建
debounce.ts
文件 (防抖指令)
import type { Directive, DirectiveBinding } from "vue";
interface ElType extends HTMLElement {__handleClick__: () => any;
}
const debounce: Directive = {mounted(el: ElType, binding: DirectiveBinding) {if (typeof binding.value !== "function") {throw "callback must be a function";}let timer: number | null = null;el.__handleClick__ = function () {if (timer) {clearInterval(timer);}timer = setTimeout(() => {binding.value();}, 500);};el.addEventListener("click", el.__handleClick__);},beforeUnmount(el: ElType) {el.removeEventListener("click", el.__handleClick__);}
};export default debounce;
- 新建
throttle.ts
文件 (节流指令)
import type { Directive, DirectiveBinding } from "vue";
interface ElType extends HTMLElement {__handleClick__: () => any;disabled: boolean;
}
const throttle: Directive = {mounted(el: ElType, binding: DirectiveBinding) {if (typeof binding.value !== "function") {throw "callback must be a function";}let timer: number | null = null;el.__handleClick__ = function () {if (timer) {clearTimeout(timer);}if (!el.disabled) {el.disabled = true;binding.value();timer = setTimeout(() => {el.disabled = false;}, 1000);}};el.addEventListener("click", el.__handleClick__);},beforeUnmount(el: ElType) {el.removeEventListener("click", el.__handleClick__);}
};export default throttle;
- 新建
index.ts
文件
import { App, Directive } from "vue";
import copy from "./modules/copy";
import debounce from "./modules/debounce";
import throttle from "./modules/throttle";const directivesList: { [key: string]: Directive } = {copy,debounce,throttle,
};const directives = {install: function (app: App<Element>) {Object.keys(directivesList).forEach(key => {app.directive(key, directivesList[key]);});}
};export default directives;
- 在‘
main.ts
中引入index 文件
import { createApp } from "vue";
import App from "./App.vue";
import router from "./router";
import store from "./store";
import ElementPlus from "element-plus";
import "element-plus/dist/index.css";
import directives from "@/components/directives/index"; // 在此处引入指令
const app = createApp(App)
app.use(store)
app.use(directives) // 注册
app.use(router)
app.use(ElementPlus)
app.mount("#app");
- 指令使用
<template><div class="card content-box" style="margin-top:30px"><span class="text">防抖指令</span><el-button v-debounce="debounceClick" type="primary">防抖按钮 (0.5秒后执行)</el-button></div><div class="card content-box" style="margin-top:30px"><span class="text">节流指令</span><el-button v-throttle="throttleClick" type="primary">节流按钮 (每隔1S秒后执行)</el-button></div><div style="margin-top:30px"><el-button v-copy="message">复制指令</el-button></div>
</template><script setup lang="ts" name="debounceDirect">
import { ElMessage } from "element-plus";
import { ref } from "vue";
const message = ref('这是复制指令')
const debounceClick = () => {console.log(11111111111);ElMessage.success("我是防抖按钮触发的事件");
};
const throttleClick = () => {console.log(2222222222222);ElMessage.success("我是节流按钮触发的事件");
};
</script>
- 搞定!