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