- 作者:老汪软件技巧
- 发表时间:2024-11-30 17:03
- 浏览量:
本文旨在记录解决在工作中一键复制功能得需求,使用Vue3+TypeScript+Ant-Design-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
一键复制
总结
总的来说这个自定义指令比较简单,实现这个指令是为了项目中多处地方方便使用,此文章不过多的解释其中的代码,有需要的可以直接复制到自己代码中测试一下。