vue.js

关注公众号 jb51net

关闭
首页 > 网络编程 > JavaScript > javascript类库 > vue.js > vue一键复制

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

作者:你我皆牛马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一键复制的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:
阅读全文