6 changed files with 29 additions and 109 deletions
@ -1,69 +0,0 @@
|
||||
import { ref, watch } from 'vue' |
||||
|
||||
import { isDef } from '@/utils/is' |
||||
|
||||
interface Options { |
||||
target?: HTMLElement |
||||
} |
||||
export function useCopyToClipboard(initial?: string) { |
||||
const clipboardRef = ref(initial || '') |
||||
const isSuccessRef = ref(false) |
||||
const copiedRef = ref(false) |
||||
|
||||
watch( |
||||
clipboardRef, |
||||
(str?: string) => { |
||||
if (isDef(str)) { |
||||
copiedRef.value = true |
||||
isSuccessRef.value = copyTextToClipboard(str) |
||||
} |
||||
}, |
||||
{ immediate: !!initial, flush: 'sync' }, |
||||
) |
||||
|
||||
return { clipboardRef, isSuccessRef, copiedRef } |
||||
} |
||||
|
||||
export function copyTextToClipboard(input: string, { target = document.body }: Options = {}) { |
||||
const element = document.createElement('textarea') |
||||
const previouslyFocusedElement = document.activeElement |
||||
|
||||
element.value = input |
||||
|
||||
element.setAttribute('readonly', '') |
||||
;(element.style as any).contain = 'strict' |
||||
element.style.position = 'absolute' |
||||
element.style.left = '-9999px' |
||||
element.style.fontSize = '12pt' |
||||
|
||||
const selection = document.getSelection() |
||||
let originalRange |
||||
if (selection && selection.rangeCount > 0) |
||||
originalRange = selection.getRangeAt(0) |
||||
|
||||
target.append(element) |
||||
element.select() |
||||
|
||||
element.selectionStart = 0 |
||||
element.selectionEnd = input.length |
||||
|
||||
let isSuccess = false |
||||
try { |
||||
isSuccess = document.execCommand('copy') |
||||
} |
||||
catch (e: any) { |
||||
throw new Error(e) |
||||
} |
||||
|
||||
element.remove() |
||||
|
||||
if (originalRange && selection) { |
||||
selection.removeAllRanges() |
||||
selection.addRange(originalRange) |
||||
} |
||||
|
||||
if (previouslyFocusedElement) { |
||||
;(previouslyFocusedElement as HTMLElement).focus() |
||||
} |
||||
return isSuccess |
||||
} |
@ -0,0 +1,12 @@
|
||||
import { message } from 'ant-design-vue' |
||||
|
||||
export function copyText(text: string, prompt: string | null = '已成功复制到剪切板!') { |
||||
navigator.clipboard.writeText(text).then( |
||||
() => { |
||||
prompt && message.success(prompt) |
||||
}, |
||||
(error: Error) => { |
||||
message.error(`复制失败!${error.message}`) |
||||
}, |
||||
) |
||||
} |
Reference in new issue