
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