clipboard-copy、copy-to-clipboard、ngclipboard、react-copy-to-clipboard 和 vue-clipboard2 都是用于在浏览器中实现文本复制到系统剪贴板功能的 npm 包,但它们面向不同的技术栈和使用场景。clipboard-copy 是一个极简的原生 JavaScript 工具函数,不依赖任何框架;copy-to-clipboard 同样是框架无关的通用库,提供 Promise 支持和更完整的错误处理;ngclipboard 是为 Angular 应用设计的指令封装;react-copy-to-clipboard 专为 React 提供组件和 Hook 式 API;vue-clipboard2 则是为 Vue 2 生态构建的插件(注意:官方已明确不再维护,且不支持 Vue 3)。这些库的核心目标一致 —— 安全、可靠地调用现代 Clipboard API 或回退到传统方案(如临时 textarea)以完成复制操作。
在 Web 应用中实现“一键复制”功能看似简单,实则涉及浏览器兼容性、安全策略(如用户手势要求)、API 降级(从现代 Clipboard API 回退到 document.execCommand)等复杂细节。上述五个库都试图简化这一过程,但设计理念、适用场景和技术栈绑定程度差异显著。本文将从核心能力、API 设计、错误处理和框架集成四个维度进行深度剖析。
所有库都优先尝试使用 现代 Clipboard API(navigator.clipboard.writeText),因其更安全、异步且无需创建 DOM 元素。若不可用(如旧版浏览器或非安全上下文),则回退到 document.execCommand('copy') 方案 —— 通过动态创建隐藏的 <textarea>,聚焦后执行命令。
clipboard-copy 采用最简实现:直接调用 writeText,失败时静默回退到 execCommand,不暴露错误信息。
// clipboard-copy
import copy from 'clipboard-copy';
copy('要复制的文本'); // 无返回值,无错误处理
copy-to-clipboard 同样自动降级,但返回 Promise,并在所有路径下统一 resolve/reject,便于业务逻辑判断。
// copy-to-clipboard
import copy from 'copy-to-clipboard';
copy('文本').then(success => {
if (success) console.log('复制成功');
else console.warn('复制失败');
});
ngclipboard、react-copy-to-clipboard 和 vue-clipboard2 均基于上述两种底层方案之一(通常是 copy-to-clipboard 或自实现),在其上增加框架层抽象,因此错误处理能力取决于底层实现。
⚠️ 注意:
vue-clipboard2的底层实现较旧,部分场景下在 iOS Safari 中可能失效,且无活跃维护修复。
clipboard-copy 提供纯函数接口,调用即执行,无状态:
import clipboardCopy from 'clipboard-copy';
document.getElementById('btn').onclick = () => {
clipboardCopy('Hello World');
};
copy-to-clipboard 同样是函数式,但支持选项配置(如是否使用 execCommand 强制回退):
import copy from 'copy-to-clipboard';
copy('文本', { format: 'text/plain' }); // 支持 MIME 类型(仅 Clipboard API 有效)
react-copy-to-clipboard 提供两种用法:
import { CopyToClipboard } from 'react-copy-to-clipboard';
function App() {
return (
<CopyToClipboard text="要复制的内容" onCopy={() => alert('已复制')}>
<button>复制</button>
</CopyToClipboard>
);
}
import { useCopyToClipboard } from 'react-copy-to-clipboard';
function App() {
const [value, copy] = useCopyToClipboard();
return (
<button onClick={() => copy('动态文本')}>
{value ? '✅ 复制成功' : '复制'}
</button>
);
}
ngclipboard 通过指令实现,符合 Angular 模板语法:
// app.module.ts
import { NgClipBoardModule } from 'ngclipboard';
@NgModule({ imports: [NgClipBoardModule] })
<!-- template.html -->
<button
ngclipboard
[cbContent]="'要复制的文本'"
(cbOnSuccess)="onCopied()"
(cbOnError)="onError($event)">
复制
</button>
vue-clipboard2 作为插件注册全局指令:
// main.js
import VueClipboard from 'vue-clipboard2';
Vue.use(VueClipboard);
<!-- component.vue -->
<template>
<button v-clipboard:copy="text" v-clipboard:success="onCopy">复制</button>
</template>
<script>
export default {
data() { return { text: 'Hello' }; },
methods: {
onCopy() { alert('成功'); }
}
}
</script>
❗ 重要提示:
vue-clipboard2官方仓库(https://github.com/Inndy/vue-clipboard2)已明确标注 “This project is no longer maintained.”,且无 Vue 3 支持计划。新项目应避免使用。
| 包名 | 错误反馈方式 | 是否可捕获失败原因 |
|---|---|---|
clipboard-copy | 无 | ❌ |
copy-to-clipboard | Promise reject / 回调 | ✅ |
ngclipboard | (cbOnError) 事件 | ✅(依赖底层) |
react-copy-to-clipboard | onCopy 回调参数 | ✅(依赖底层) |
vue-clipboard2 | v-clipboard:error 事件 | ⚠️(部分场景失效) |
例如,copy-to-clipboard 能明确区分是权限拒绝还是 API 不可用:
import copy from 'copy-to-clipboard';
copy('test').catch(err => {
if (err.name === 'NotAllowedError') {
alert('请允许剪贴板权限');
} else {
alert('浏览器不支持');
}
});
而 clipboard-copy 在相同场景下会静默失败,开发者无法感知。
clipboard-copy 和 copy-to-clipboard 是框架无关库,可安全用于任何项目,包括 Svelte、Solid 或原生 JS。两者均保持更新以适配浏览器变更。ngclipboard 专为 Angular 设计,但最近版本发布间隔较长,需自行验证与 Angular 16+/17 的兼容性。react-copy-to-clipboard 积极维护,支持 React 18 并提供 Hook API,是 React 项目的首选。vue-clipboard2 已废弃,不应在新项目中使用。Vue 3 用户应考虑:
copy-to-clipboard 封装自定义指令;@vueuse/core 的 useClipboard。clipboard-copycopy-to-clipboardreact-copy-to-clipboardngclipboard(需验证兼容性)copy-to-clipboard,避免指令依赖。vue-clipboard2(因历史原因)copy-to-clipboard + 自定义指令。| 特性 | clipboard-copy | copy-to-clipboard | ngclipboard | react-copy-to-clipboard | vue-clipboard2 |
|---|---|---|---|---|---|
| 框架绑定 | 无 | 无 | Angular | React | Vue 2 |
| API 风格 | 函数 | 函数 | 指令 | 组件/Hook | 指令 |
| 错误处理 | 无 | Promise/回调 | 事件 | 回调 | 事件(部分失效) |
| 维护状态 | 活跃 | 活跃 | 低频更新 | 活跃 | 已废弃 |
| 适用新项目 | ✅ | ✅ | ⚠️ | ✅ | ❌ |
copy-to-clipboard:它在通用性、健壮性和易用性之间取得了最佳平衡,即使你在 React/Angular 项目中,也可将其作为底层依赖自行封装。react-copy-to-clipboard:省去封装成本,享受框架优化。vue-clipboard2:技术债风险高,替代方案成熟。clipboard-copy:牺牲错误处理换取极致轻量。剪贴板操作虽小,却直接影响用户体验。选对工具,能让“复制”这一简单动作变得既可靠又优雅。
选择 clipboard-copy 如果你追求极致轻量、无依赖、仅需一行函数调用即可完成复制操作,且项目不涉及复杂的错误处理或 Promise 流程。它适合嵌入工具库、微前端子应用或对 bundle size 极度敏感的场景。但需注意它不返回 Promise,也不提供失败回调,仅适用于“尽力而为”式的简单复制需求。
选择 copy-to-clipboard 如果你需要一个跨框架、稳定可靠的通用解决方案,并希望获得 Promise 支持、明确的错误反馈以及对现代 Clipboard API 的自动降级处理。它适合大多数非框架绑定的项目,尤其是需要在业务逻辑中根据复制结果执行后续操作(如显示成功/失败提示)的场景。
选择 ngclipboard 如果你的项目基于 Angular(特别是 Angular 8+),并希望通过指令(directive)方式在模板中声明式地实现复制功能。它封装了底层细节,提供 cbContent、cbSuccess 等输入输出属性,符合 Angular 开发习惯。但需确认其与当前 Angular 版本的兼容性,因维护活跃度有限。
选择 react-copy-to-clipboard 如果你正在开发 React 应用,并希望以组件或自定义 Hook 的形式集成复制功能。它提供 <CopyToClipboard> 组件和 useCopyToClipboard Hook(需 v5.1+),能无缝融入 React 状态管理,适合需要响应式 UI 反馈(如按钮文字变化)的交互场景。
选择 vue-clipboard2 仅当你维护的是 Vue 2 遗留项目,且无法升级或替换方案。该库通过 Vue 插件形式注册全局指令 v-clipboard,使用简单。但官方 GitHub 明确标注“不再维护”,且完全不支持 Vue 3。新项目应避免使用,建议改用原生 Clipboard API 或 copy-to-clipboard 封装自定义指令。
The goal of this package is to offer simple copy-to-clipboard functionality in modern web browsers using the fewest bytes. To do so, this package only supports modern browsers. No fallback using Adobe Flash, no hacks. Just 30 lines of code.
Unlike other implementations, text copied with clipboard-copy is clean and
unstyled. Copied text will not inherit HTML/CSS styling like the page's background
color.
Supported browsers: Chrome, Firefox, Edge, Safari.
Works in the browser with browserify!
npm install clipboard-copy
const copy = require('clipboard-copy')
button.addEventListener('click', function () {
copy('This is some cool text')
})
successPromise = copy(text)Copy the given text to the user's clipboard. Returns successPromise, a promise that resolves if the copy was successful and rejects if the copy failed.
Note: in most browsers, copying to the clipboard is only allowed if copy() is
triggered in direct response to a user gesture like a 'click' or a 'keypress'.
clipboard-copy (this package): 524 B gzippedclipboard-js: 1.7 kB gzippedclipboard: 3.2 kB gzippedTesting this module is currently a manual process. Open test.html in your web browser and follow the short instructions. The web page will always load the latest version of the module, no bundling is necessary.
MIT. Copyright (c) Feross Aboukhadijeh.