feat: 增强前端clipboard功能
This commit is contained in:
@@ -1,40 +1,65 @@
|
||||
import { ref } from 'vue'
|
||||
import { useAppStore } from '@/stores/app'
|
||||
|
||||
/**
|
||||
* 检测是否支持 Clipboard API(需要安全上下文:HTTPS/localhost)
|
||||
*/
|
||||
function isClipboardSupported(): boolean {
|
||||
return !!(navigator.clipboard && window.isSecureContext)
|
||||
}
|
||||
|
||||
/**
|
||||
* 降级方案:使用 textarea + execCommand
|
||||
* 使用 textarea 而非 input,以正确处理多行文本
|
||||
*/
|
||||
function fallbackCopy(text: string): boolean {
|
||||
const textarea = document.createElement('textarea')
|
||||
textarea.value = text
|
||||
textarea.style.cssText = 'position:fixed;left:-9999px;top:-9999px'
|
||||
document.body.appendChild(textarea)
|
||||
textarea.select()
|
||||
try {
|
||||
return document.execCommand('copy')
|
||||
} finally {
|
||||
document.body.removeChild(textarea)
|
||||
}
|
||||
}
|
||||
|
||||
export function useClipboard() {
|
||||
const appStore = useAppStore()
|
||||
const copied = ref(false)
|
||||
|
||||
const copyToClipboard = async (text: string, successMessage = 'Copied to clipboard') => {
|
||||
const copyToClipboard = async (
|
||||
text: string,
|
||||
successMessage = 'Copied to clipboard'
|
||||
): Promise<boolean> => {
|
||||
if (!text) return false
|
||||
|
||||
try {
|
||||
await navigator.clipboard.writeText(text)
|
||||
copied.value = true
|
||||
appStore.showSuccess(successMessage)
|
||||
setTimeout(() => {
|
||||
copied.value = false
|
||||
}, 2000)
|
||||
return true
|
||||
} catch {
|
||||
// Fallback for older browsers
|
||||
const input = document.createElement('input')
|
||||
input.value = text
|
||||
document.body.appendChild(input)
|
||||
input.select()
|
||||
document.execCommand('copy')
|
||||
document.body.removeChild(input)
|
||||
copied.value = true
|
||||
appStore.showSuccess(successMessage)
|
||||
setTimeout(() => {
|
||||
copied.value = false
|
||||
}, 2000)
|
||||
return true
|
||||
let success = false
|
||||
|
||||
if (isClipboardSupported()) {
|
||||
try {
|
||||
await navigator.clipboard.writeText(text)
|
||||
success = true
|
||||
} catch {
|
||||
success = fallbackCopy(text)
|
||||
}
|
||||
} else {
|
||||
success = fallbackCopy(text)
|
||||
}
|
||||
|
||||
if (success) {
|
||||
copied.value = true
|
||||
appStore.showSuccess(successMessage)
|
||||
setTimeout(() => {
|
||||
copied.value = false
|
||||
}, 2000)
|
||||
} else {
|
||||
appStore.showError('Copy failed')
|
||||
}
|
||||
|
||||
return success
|
||||
}
|
||||
|
||||
return {
|
||||
copied,
|
||||
copyToClipboard
|
||||
}
|
||||
return { copied, copyToClipboard }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user