vue自定义指令实现一键复制功能

 更新时间:2024年11月30日 15:41:10   作者:你我皆牛马MC  
本文旨在记录解决在工作中一键复制功能得需求,本文主要使用了Vue3+TypeScript+Ant-Design-Vue,感兴趣的小伙伴可以跟随小编一起学习一下

什么是vue自定义指令?请移步Vue自定义指令

实现的指令兼容了不支持navigator.clipboard API的浏览器,且实现了节流的效果,默认间隔时间1000ms

1、创建一个文件,比如:copy.ts

import { notification } from 'ant-design-vue'

// 自定义一些属性
interface IListenter {
  (event: MouseEvent): void
}

interface ICopyElement extends HTMLElement {
  $value: string
  $isSupported: boolean
  $isClick: boolean
  $timer: number
  $handleCopy: IListenter
}

const useCopy = (app: ReturnType<typeof createApp>) => {
  app.directive('copy', {
    mounted(el: ICopyElement, binding: ReturnType<typeof Object>) {
      console.log(binding)
      let timer = binding.arg?.split(':')[0] || ''
      // 判断timer是否存在,且是否为数字,如果不是数字则赋值默认值 1000ms
      if (timer && parseInt(timer) != timer) {
        el.$timer = parseInt(timer)
      } else {
        el.$timer = 1000
      }
      el.$value = binding.value

      el.$handleCopy = async (event: MouseEvent) => {
        // 简单做个节流
        if (el.$isClick) return
        el.$isClick = true
        let t = setTimeout(() => {
          clearTimeout(t)
          el.$isClick = false
        }, el.$timer)

        if (!el.$value) {
          // 值为空的时候,给出提示
          notification.warning({ message: '系统提示', description: '无复制内容' })
          return
        }
        // 获取是否支持复制api
        if (el.$isSupported === undefined) {
          el.$isSupported = navigator && 'clipboard' in navigator
        }
        // 判断浏览器是否支持 navigator.clipboard
        if (!el.$isSupported) {
          // 不支持,使用旧的复制方式
          // 动态创建 textarea 标签
          const textarea = document.createElement('textarea')
          // 将该 textarea 设为 readonly 防止 iOS 下自动唤起键盘,同时将 textarea 移出可视区域
          textarea.readOnly = true
          textarea.style.position = 'fixed'
          textarea.style.left = '-9999px'
          // 将要 copy 的值赋给 textarea 标签的 value 属性
          textarea.value = el.$value
          // 将 textarea 插入到 body 中
          document.body.appendChild(textarea)
          // 选中值并复制
          textarea.select()
          // textarea.setSelectionRange(0, textarea.value.length);
          const result = document.execCommand('Copy')
          if (result) {
            notification.success({ message: '系统提示', description: '复制成功' })
          }
          document.body.removeChild(textarea)
        } else {
          // 使用 clipboard API
          await navigator!.clipboard.writeText(el.$value)
          notification.success({ message: '系统提示', description: '复制成功' })
        }
      }
      el.addEventListener('click', el.$handleCopy, false)
    },
    unmounted(el: ICopyElement) {
      el.removeEventListener('click', el.$handleCopy)
    }
  })
}

export default (app: ReturnType<typeof createApp>) => {
  useCopy(app)
}

2、在main.ts文件中使用

import App from './App.vue'
import * as copyFn from './copy' // 上面创建的文件
const app = createApp(App)

if (typeof copyFn.default === 'function') {
    copyFn.default(app)
}
app.mount('#app')

上面的写法可以根据自己项目中的情况改变

3、使用

// test.vue
<template>
    <!-- 使用默认的间隔时间 -->
    <a-button v-copy="value">一键复制</a-button>
    
    <!-- 自定义间隔时间 -->
    <!-- <a-button v-copy:2000="value">一键复制</a-button> -->
</template>

<script lang="ts" setup>
import {ref} from 'vue'

const value = ref('这是一个自定义一键复制的指令')

</script>

总结

总的来说这个自定义指令比较简单,实现这个指令是为了项目中多处地方方便使用,此文章不过多的解释其中的代码,有需要的可以直接复制到自己代码中测试一下。

以上就是vue自定义指令实现一键复制功能的详细内容,更多关于vue一键复制的资料请关注脚本之家其它相关文章!

相关文章

  • vue中的事件修饰符介绍和示例

    vue中的事件修饰符介绍和示例

    在Vue中,修饰符处理了许多DOM事件的细节,让我们不再需要花大量的时间去处理这些烦恼的事情,而能有更多的精力专注于程序的逻辑处理,需要的朋友可以参考下
    2023-04-04
  • vue子组件中mounted取不到props中的值情况

    vue子组件中mounted取不到props中的值情况

    这篇文章主要介绍了vue子组件中mounted取不到props中的值情况,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-04-04
  • Vue3不支持Filters过滤器的问题

    Vue3不支持Filters过滤器的问题

    这篇文章主要介绍了Vue3不支持Filters过滤器的问题,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-09-09
  • 前端Uniapp使用Vant打造Uniapp项目避坑指南

    前端Uniapp使用Vant打造Uniapp项目避坑指南

    这篇文章主要给大家介绍了关于前端Uniapp使用Vant打造Uniapp项目避坑的相关资料,Uniapp结合Vant可以快速构建跨平台移动应用,通过HBuilderX安装和配置Vant组件,解决了样式识别问题,并实现了组件的全局注册,需要的朋友可以参考下
    2024-11-11
  • vue2 web多标签输入框elinput是否当前焦点详解

    vue2 web多标签输入框elinput是否当前焦点详解

    这篇文章主要介绍了vue2 web多标签输入框elinput是否当前焦点的相关资料,讲解了如何在产品中实现用户输入文字后按下回车键生成标签并显示在页面上的功能,通过组件的使用和改造,解决了输入不连续的问题,需要的朋友可以参考下
    2025-01-01
  • vue2创建高复用组件的方法示例

    vue2创建高复用组件的方法示例

    Vue2中的高复用组件通常是指那些设计得足够通用,并能多次在项目中重复使用的组件,本文给大家详细介绍了vue2创建高复用组件的方法示例,并通过代码示例讲解的非常详细,需要的朋友可以参考下
    2024-07-07
  • 浅析为什么Vue使用虚拟DOM

    浅析为什么Vue使用虚拟DOM

    Vue 使用虚拟 DOM 的初衷不仅是为了性能优化,更重要的是为了解决开发效率和灵活性的问题,下面我们就来探讨一下虚拟DOM的作用与原理吧
    2024-12-12
  • Vue使用babel-polyfill兼容IE解决白屏及语法报错问题

    Vue使用babel-polyfill兼容IE解决白屏及语法报错问题

    这篇文章主要介绍了Vue使用babel-polyfill兼容IE解决白屏及语法报错问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-03-03
  • Vue解决跨域问题常见方法详解

    Vue解决跨域问题常见方法详解

    这篇文章主要介绍了Vue解决跨域问题常见方法,结合实例形式详细分析了vue出现跨域问题的原因,以及常见解决方案与相关注意事项,需要的朋友可以参考下
    2023-06-06
  • Nuxt3:拉取项目模板失败问题以及解决

    Nuxt3:拉取项目模板失败问题以及解决

    文章描述了在使用官网命令创建Nuxt3项目时遇到的问题,通过分析命令,推测问题出在拉取项目模板失败,解决方法是手动访问并下载项目模板,解压后按照官网教程安装依赖并启动,最终成功解决问题
    2024-12-12

最新评论