必须先转成字符串再调用 uni.setClipboardData,因其 data 参数只接受字符串;传入数组或对象会自动转为 "[object Object]" 等字面量,导致剪贴板为空;应使用 JSON.stringify 安全序列化,并注意权限、调用时机及环境限制。

必须先转成字符串,再调用 uni.setClipboardData,否则会静默失败——传 Array 或 Object 进去,API 不报错但剪贴板里是空的。
为什么不能直接复制数组对象
uni.setClipboardData 的 data 参数只接受字符串。传入 [{id: 1}] 或 {name: "test"} 会被自动转成 "[object Object]" 或 "[object Array]",最终粘贴出来就是这两个字面量。
- 不是浏览器限制,是 uni-app 这个 API 的硬性要求
- 即使在 H5 端用
navigator.clipboard.writeText,也一样只收字符串 - 小程序/APP 端不会抛错,但结果为空;H5 端可能直接 reject
怎么安全地把数组对象转成可复制的字符串
优先用 JSON.stringify,它能处理大多数结构,且兼容所有端(包括低版本 iOS 和旧 Android)。
- 简单数组:
JSON.stringify([1, 2, 3])→"[1,2,3]" - 对象数组:
JSON.stringify([{name: "张三"}, {name: "李四"}])→"[{\"name\":\"张三\"},{\"name\":\"李四\"}]" - 如果要人眼可读,加缩进:
JSON.stringify(data, null, 2) - 遇到循环引用、函数、undefined 字段会报错,此时需提前过滤或用自定义序列化(比如
jsonTypeConversion(data, 'string')封装兜底)
复制时容易踩的坑
哪怕字符串准备对了,uni.setClipboardData 仍可能静默失败。
- 调用必须在用户手势触发的第一层回调里:
@click="handleCopy"中直接写,不能包在setTimeout、this.$nextTick、Promise.then里 - App 端缺权限会失败:iOS 要在
manifest.json→「App 设置」→「iOS 设置」勾选「剪贴板」;Android 要在「模块权限配置」启用clipboard模块 - 小程序端(尤其微信)必须在
mp-weixin下声明:"scope.writeClipboard": true,否则真机提示permission-denied - H5 端只支持 HTTPS 或
localhost(注意不是127.0.0.1),非安全上下文会抛NotAllowedError
完整可运行示例
methods: {
async handleCopy() {
const list = [{ id: 1, name: '苹果' }, { id: 2, name: '香蕉' }]
const text = JSON.stringify(list, null, 2) // 格式化输出,方便阅读
try {
await uni.setClipboardData({ data: text })
uni.showToast({ title: '已复制', icon: 'none' })
} catch (err) {
console.error('复制失败', err)
uni.showToast({ title: '复制失败', icon: 'none' })
}
}
}
注意:如果后端返回的是带 undefined 或 Date 实例的原始数据,JSON.stringify 会丢字段或转成空字符串,这种场景得先做清洗,不能跳过这步直接塞进去。











