v-copyText 自定义指令 ------ 复制文本内容
简介
v-copyText
是一个用于 Vue.js 项目的自定义指令,它允许用户点击元素后自动复制文本内容到剪贴板,并支持回调函数处理复制成功后的逻辑。
代码实现
ini
/**
* v-copyText 自定义指令 - 复制文本内容到剪贴板
* Copyright (c) 2022 ruoyi
*/
export default {
beforeMount(el, { value, arg }) {
// 如果指令的参数是 "callback",则将回调函数存储在元素上
if (arg === "callback") {
el.$copyCallback = value;
} else {
// 否则,将复制的内容存储在元素上
el.$copyValue = value;
// 定义点击事件处理函数
const handler = () => {
// 调用复制文本到剪贴板的函数
copyTextToClipboard(el.$copyValue);
// 如果存在回调函数,则执行回调
if (el.$copyCallback) {
el.$copyCallback(el.$copyValue);
}
};
// 监听点击事件,点击时触发复制操作
el.addEventListener("click", handler);
// 存储销毁函数,用于移除事件监听
el.$destroyCopy = () => el.removeEventListener("click", handler);
}
}
}
/**
* 复制文本到剪贴板
* @param {string} input - 要复制的文本内容
* @param {Object} options - 额外选项,可指定目标元素
*/
function copyTextToClipboard(input, { target = document.body } = {}) {
// 创建一个 textarea 元素用于复制
const element = document.createElement('textarea');
// 记录当前焦点的元素
const previouslyFocusedElement = document.activeElement;
// 设置 textarea 的值为需要复制的文本
element.value = input;
// 使文本框只读,防止移动端弹出键盘
element.setAttribute('readonly', '');
// 设置样式,确保不会影响页面布局
element.style.contain = 'strict';
element.style.position = 'absolute';
element.style.left = '-9999px';
element.style.fontSize = '12pt'; // 防止 iOS 上的自动缩放
// 记录当前选区
const selection = document.getSelection();
const originalRange = selection.rangeCount > 0 && selection.getRangeAt(0);
// 将 textarea 添加到页面
target.append(element);
// 选中文本
element.select();
// 解决 iOS 兼容性问题,手动设置选择范围
element.selectionStart = 0;
element.selectionEnd = input.length;
let isSuccess = false;
try {
// 执行复制命令
isSuccess = document.execCommand('copy');
} catch { }
// 复制完成后移除 textarea 元素
element.remove();
// 恢复之前的选区
if (originalRange) {
selection.removeAllRanges();
selection.addRange(originalRange);
}
// 将焦点恢复到之前的元素
if (previouslyFocusedElement) {
previouslyFocusedElement.focus();
}
return isSuccess;
}
代码解析
1. 自定义指令 v-copyText
- 该指令用于在元素上绑定点击复制功能。
beforeMount
钩子在指令绑定到元素之前触发。- 如果
arg === "callback"
,则将回调函数存储到el.$copyCallback
,以便在复制完成后调用。 - 否则,将要复制的文本存储在
el.$copyValue
,并绑定click
事件执行复制逻辑。
2. copyTextToClipboard
函数
- 创建
textarea
元素,写入需要复制的文本。 - 通过
document.execCommand('copy')
执行复制操作。 - 移除
textarea
并恢复用户之前的选区和焦点。
使用方式
1. 在 Vue 组件中使用
xml
<template>
<button v-copyText="'要复制的文本'">点击复制</button>
</template>
2. 使用回调函数
xml
<template>
<button v-copyText:callback="copySuccess">点击复制</button>
</template>
<script>
export default {
methods: {
copySuccess(text) {
console.log(`复制成功: ${text}`);
}
}
}
</script>
结论
v-copyText
是一个简单而实用的 Vue 自定义指令,可以轻松实现点击复制文本的功能,并且支持回调函数处理复制成功后的逻辑,非常适用于需要复制文本内容的场景,比如分享链接、邀请码、文本复制等功能。