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