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

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. 搞定!
  • 9
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
对于Vue 3和TypeScript结合使用Element Plus进行懒加载指令的封装,可以按照以下步骤进行: 1. 创建一个新的文件,例如`lazyLoadDirective.ts`,在其中导入Vue、Directive和IntersectionObserver。 ```typescript import { App, Directive, DirectiveBinding } from 'vue'; import { DirectiveOptions } from 'vue'; // 导入IntersectionObserver import IntersectionObserver from 'intersection-observer'; // 创建指令选项对象 const lazyLoadDirective: DirectiveOptions = { // 指令生命周期钩子函数 mounted(el: HTMLElement, binding: DirectiveBinding) { // 创建IntersectionObserver实例 const observer = new IntersectionObserver((entries) => { // 当目标元素进入可视区域时加载内容 if (entries[0].isIntersecting) { // 执行绑定的回调函数 binding.value(); // 关闭观察器 observer.disconnect(); } }); // 开始观察目标元素 observer.observe(el); } }; // 导出指令对象 export default lazyLoadDirective; ``` 2. 在`main.ts`文件中导入并注册该指令。 ```typescript import { createApp } from 'vue'; import App from './App.vue'; import lazyLoadDirective from './lazyLoadDirective.ts'; const app = createApp(App); // 注册指令 app.directive('lazyload', lazyLoadDirective); app.mount('#app'); ``` 3. 在组件中使用指令。 ```html <template> <div v-lazyload="loadContent">Lazy Load Content</div> </template> <script> export default { methods: { loadContent() { // 加载内容的逻辑 } } } </script> ``` 以上是一种简单的方式来封装懒加载指令。请注意,此代码仅供参考,你可能需要根据具体的需求进行适当的修改和调整。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值