mirror of
https://github.com/vbenjs/vue-vben-admin.git
synced 2025-01-26 12:48:48 +08:00
70 lines
1.6 KiB
TypeScript
70 lines
1.6 KiB
TypeScript
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) {
|
|
throw new Error(e);
|
|
}
|
|
|
|
element.remove();
|
|
|
|
if (originalRange && selection) {
|
|
selection.removeAllRanges();
|
|
selection.addRange(originalRange);
|
|
}
|
|
|
|
if (previouslyFocusedElement) {
|
|
(previouslyFocusedElement as HTMLElement).focus();
|
|
}
|
|
return isSuccess;
|
|
}
|