
4 changed files with 180 additions and 46 deletions
@ -0,0 +1,80 @@ |
|||||
|
/** |
||||
|
* 复制文本到剪贴板 |
||||
|
* @param {string} text 要复制的文本 |
||||
|
* @param {Object} options 配置选项 |
||||
|
* @param {string} options.successMsg 成功提示信息 |
||||
|
* @param {string} options.errorMsg 失败提示信息 |
||||
|
* @param {Vue} options.vm Vue实例(用于调用$message) |
||||
|
* @returns {Promise<boolean>} 是否复制成功 |
||||
|
*/ |
||||
|
export function copyToClipboard(text, options = {}) { |
||||
|
const { |
||||
|
successMsg = '复制成功', |
||||
|
errorMsg = '复制失败,请手动复制', |
||||
|
vm = null |
||||
|
} = options; |
||||
|
|
||||
|
return new Promise((resolve) => { |
||||
|
// 创建textarea元素
|
||||
|
const textarea = document.createElement('textarea'); |
||||
|
textarea.value = text; |
||||
|
textarea.style.position = 'fixed'; // 防止页面滚动
|
||||
|
document.body.appendChild(textarea); |
||||
|
textarea.select(); |
||||
|
|
||||
|
try { |
||||
|
// 执行复制命令
|
||||
|
const successful = document.execCommand('copy'); |
||||
|
if (successful) { |
||||
|
if (vm && vm.$Message) { |
||||
|
vm.$Message.success(successMsg); |
||||
|
} else { |
||||
|
console.log(successMsg); |
||||
|
} |
||||
|
resolve(true); |
||||
|
} else { |
||||
|
throw new Error('Copy command was unsuccessful'); |
||||
|
} |
||||
|
} catch (err) { |
||||
|
console.error('复制失败:', err); |
||||
|
if (vm && vm.$Message) { |
||||
|
vm.$Message.error(errorMsg); |
||||
|
} else { |
||||
|
console.error(errorMsg); |
||||
|
} |
||||
|
resolve(false); |
||||
|
} finally { |
||||
|
document.body.removeChild(textarea); |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @param {string} text 要复制的文本 |
||||
|
* @param {Object} options 配置选项 |
||||
|
* @returns {Promise<boolean>} 是否复制成功 |
||||
|
*/ |
||||
|
export async function modernCopyToClipboard(text, options = {}) { |
||||
|
const { |
||||
|
successMsg = '复制成功', |
||||
|
errorMsg = '复制失败,请手动复制', |
||||
|
vm = null |
||||
|
} = options; |
||||
|
|
||||
|
try { |
||||
|
// 使用现代剪贴板API
|
||||
|
await navigator.clipboard.writeText(text); |
||||
|
if (vm && vm.$Message) { |
||||
|
vm.$Message.success(successMsg); |
||||
|
} else { |
||||
|
console.log(successMsg); |
||||
|
} |
||||
|
return true; |
||||
|
} catch (err) { |
||||
|
console.error(errorMsg, err); |
||||
|
// 现代API失败后回退到传统方法
|
||||
|
return copyToClipboard(text, options); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
export default modernCopyToClipboard; |
@ -0,0 +1,19 @@ |
|||||
|
import modernCopyToClipboard from '@/utils/clipboard'; |
||||
|
|
||||
|
export default { |
||||
|
install(Vue) { |
||||
|
Vue.directive('clipboard', { |
||||
|
bind(el, binding) { |
||||
|
el.style.cursor = 'pointer'; |
||||
|
el.addEventListener('click', async () => { |
||||
|
const text = binding.value || el.innerText; |
||||
|
const options = { |
||||
|
vm: binding.instance, |
||||
|
...(binding.arg || {}) |
||||
|
}; |
||||
|
await modernCopyToClipboard(text, options); |
||||
|
}); |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
}; |
Loading…
Reference in new issue