vue3 + ts 防抖指令,节流指令,复制指令

2023-12-13 06:16:11

vue3 + ts 自定义指令 防抖指令,节流指令,复制指令

  1. 本文使用了 element-ui , element-plus 官网

  2. 源文件 https://admin.spicyboy.cn/#/directives/debounceDirect

  3. 在这里插入图片描述

  4. 新建 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;
  1. 新建 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;

  1. 新建 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;
  1. 新建 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;
  1. 在‘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");
  1. 指令使用
<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>

在这里插入图片描述

  1. 搞定!

文章来源:https://blog.csdn.net/weixin_45563734/article/details/134948458
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。