useClipboard.js
2.43 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
import { ref } from 'vue';
/**
* 跨端剪贴板组合式函数 (JavaScript 版)
*/
export function useClipboard() {
const isCopying = ref(false);
const copyText = async (text, options = {}) => {
if (!text) return false;
if (isCopying.value) return false; // 简易防抖锁
isCopying.value = true;
const successText = options.successText || '复制成功';
const failText = options.failText || '复制失败';
return new Promise((resolve) => {
// #ifdef MP-WEIXIN || APP-PLUS || MP-ALIPAY
uni.setClipboardData({
data: text,
showToast: false, // 隐藏原生沉浸式提示,采用全端统一的自定义 Toast
success: () => {
uni.showToast({
title: successText,
icon: 'success',
duration: 1500,
});
resolve(true);
},
fail: (err) => {
console.error('Clipboard Error:', err);
uni.showToast({
title: failText,
icon: 'none',
});
resolve(false);
},
complete: () => {
isCopying.value = false;
},
});
// #endif
// #ifdef H5
if (navigator.clipboard && window.isSecureContext) {
navigator.clipboard
.writeText(text)
.then(() => {
uni.showToast({ title: successText, icon: 'success' });
resolve(true);
})
.catch(() => {
fallbackCopy(text, successText, failText, resolve);
})
.finally(() => {
isCopying.value = false;
});
} else {
fallbackCopy(text, successText, failText, resolve);
isCopying.value = false;
}
// #endif
});
};
// H5 降级方案
const fallbackCopy = (text, successText, failText, resolve) => {
const textarea = document.createElement('textarea');
textarea.value = text;
textarea.style.position = 'fixed';
textarea.style.opacity = '0';
document.body.appendChild(textarea);
textarea.select();
try {
const successful = document.execCommand('copy');
uni.showToast({
title: successful ? successText : failText,
icon: successful ? 'success' : 'none',
});
resolve(successful);
} catch (err) {
uni.showToast({ title: failText, icon: 'none' });
resolve(false);
}
document.body.removeChild(textarea);
};
return {
copyText,
isCopying,
};
}