uni.setclipboarddata必须传非空字符串且在用户点击事件第一层调用,否则静默失败;h5需https安全上下文,app和小程序须配置对应权限,异步获取内容时应避免脱离手势上下文。

直接用 uni.setClipboardData 就能实现,但不加判断和兜底会静默失败——比如传了 undefined、null 或数字,界面没报错,剪贴板也没变。
必须传字符串,且不能是空值或非字符串类型
这个 API 对参数极其敏感:data 字段必须是字符串。传 123、true、{}、'' 都会失败(无报错,但剪贴板内容不变)。
- 数字/布尔值要显式转成字符串:
String(this.count)或this.count + '' - 从接口取的字段,务必先判空:
if (!this.content?.trim()) return - 中文、emoji、全角空格本身没问题,但旧版微信小程序可能截断 emoji,可先
encodeURIComponent(this.text)再复制(粘贴端再decodeURIComponent)
H5 端必须用 navigator.clipboard.writeText,但 uni.setClipboardData 已内部兼容
你不需要自己写 H5 分支判断——uni.setClipboardData 在 H5 下会自动调用 navigator.clipboard.writeText,前提是运行在安全上下文(https 或 localhost)。若页面是 http 非本地调试,会直接拒绝。
- 开发时用
http://localhost:8080没问题;但部署到http://xxx.com会失败,必须上 HTTPS - 不要手动 fallback 到已废弃的
document.execCommand('copy') - 真机调试 H5 页面时,确保浏览器地址栏显示「锁形图标」,否则权限被拒
用户点击才调用,别在 onLoad 或 mounted 里自动触发
所有平台(尤其小程序和 App)都要求剪贴板操作必须由用户手势触发(click / longpress),否则会被系统拦截。自动执行等于白写。
- 按钮绑定
@click="copyText('hello')"是安全的;但mounted() { this.copyText('hello') }必定失败 - 如果文本来自异步请求,等数据回来后再渲染按钮,或加 loading 状态防止提前点击
- 长按复制场景下,
@longpress回调内调用uni.setClipboardData才有效;丢进setTimeout或Promise.then会脱离用户手势上下文,iOS 和部分安卓机直接拒绝
加反馈状态,避免重复点击和体验断层
复制成功后不给视觉反馈,用户会反复点;不防抖就可能连续触发多次,尤其网络慢时 toast 还没消失又弹一个。
- 按钮点击后立即置灰:
:disabled="isCopying",并改文字为「已复制」 - 成功回调里设
this.isCopying = true,再用setTimeout(() => { this.isCopying = false }, 2000) -
uni.showToast的duration建议设为 1200–1500ms,和按钮恢复节奏对齐 - 失败时一定要
console.error,特别是抓取err.errMsg,常见值如"setClipboardData:fail system error"(Android 后台权限被限)、"setClipboardData:fail permission denied"(H5 非安全上下文)
最常被忽略的是:复制前没清理文本中的不可见字符。从 <view></view> 里取 innerText 可能带 \u00A0(不间断空格)或换行,粘贴出来格式错乱。统一过一遍 text.replace(/[\r\n\t\s\u00A0]+/g, ' ').trim() 几乎能解决 90% 的“复制了但不对”问题。











