clipboard复制粘贴封装
使用场景
项目中有点击复制文本的功能
涉及的主要技术
使用
cnpm install clipboard --save or yarn add clipboard --save
组件里单独引入
<!-- Target -->
<input id="foo" v-model="name" />
<!-- Trigger -->
<button class="btn" data-clipboard-target="#foo" @click="copy">Copy to clipboard</button>
<script>
import ClipboardJS from 'clipboard';
export default {
data() {
return {
name: '',
};
},
methods: {
copy() {
let clipboard = new ClipboardJS('.btn');
clipboard.on('success', function (e) {
console.info('Action:', e.action);
console.info('Text:', e.text);
console.info('Trigger:', e.trigger);
e.clearSelection();
});
clipboard.on('error', function (e) {
console.error('Action:', e.action);
console.error('Trigger:', e.trigger);
});
},
}
}
</script>
- 弊端
- 每一个组件使用的时候,都要重复创建 Clipboard实例,绑定id,过程繁琐,多个组件会产生冗余代码,不好管理。
- 想要用户体验好些,需要加上响应,代码更多,需统一,项目中我使用的是elementUI
更高级的使用
方式1:封装成独立的工具库
import Vue from 'vue'
import Clipboard from 'clipboard'
function clipboardSuccess() {
Vue.prototype.$message({
message: 'Copy successfully',
type: 'success',
duration: 1500
})
}
function clipboardError() {
Vue.prototype.$message({
message: 'Copy failed',
type: 'error'
})
}
export default function handleClipboard(text, event) {
const clipboard = new Clipboard(event.target, {
text: () => text
})
clipboard.on('success', () => {
clipboardSuccess()
clipboard.destroy()
})
clipboard.on('error', () => {
clipboardError()
clipboard.destroy()
})
clipboard.onClick(event)
}
使用:
<!-- Target -->
<input v-model="name" />
<!-- Trigger -->
<button class="btn" @click="handleClipboard(name, $event)">Copy to clipboard</button>
import clip from '@/utils/clipboard';
export default {
data() {
return {
name: ''
};
},
methods: {
handleClipboard(text, event) {
clip(text, event);
}
}
};
</script>
方式2:全局自定义指令
-
文件结构
- directive/index.js
/** * 自定义指令集中管理 */ import Clipboard from './clipboard' // 复制粘贴 import Vue from 'vue'; Vue.directive('Clipboard', Clipboard);
- directive/clipboard
- directive/index.js
// Inspired by https://github.com/Inndy/vue-clipboard2
// import Vue from 'vue';
const Clipboard = require('clipboard')
if (!Clipboard) {
throw new Error('you should npm install `clipboard` --save at first ')
}
// 默认复制成功提示 UI库为element
// const clipboardSuccess = () => {
// Vue.prototype.$message({
// message: 'Copy successfully',
// type: 'success',
// duration: 500,
// })
// }
// 默认复制失败提示 UI库为element
// const clipboardError = () => {
// Vue.prototype.$message({
// message: 'Copy failed',
// type: 'error',
// duration: 500,
// })
// }
export default {
bind: function (el, binding, vnode) {
if (binding.arg === 'success') {
el._vClipboard_success = binding.value
} else if (binding.arg === 'error') {
el._vClipboard_error = binding.value
} else {
let clipboard = new Clipboard(el, {
text: function () { return binding.value },
action: function () { return binding.arg === 'cut' ? 'cut' : 'copy' },
})
clipboard.on('success', function (e) {
// let callback = el._vClipboard_success || clipboardSuccess();
let callback = el._vClipboard_success;
callback && callback(e)
})
clipboard.on('error', function (e) {
// let callback = el._vClipboard_error || clipboardError();
let callback = el._vClipboard_error;
callback && callback(e)
})
el._vClipboard = clipboard
}
},
update: function (el, binding) {
if (binding.arg === 'success') {
el._vClipboard_success = binding.value
} else if (binding.arg === 'error') {
el._vClipboard_error = binding.value
} else {
el._vClipboard.text = function () { return binding.value }
el._vClipboard.action = function () { return binding.arg === 'cut' ? 'cut' : 'copy' }
}
},
unbind: function (el, binding) {
if (binding.arg === 'success') {
delete el._vClipboard_success
} else if (binding.arg === 'error') {
delete el._vClipboard_error
} else {
el._vClipboard.destroy()
delete el._vClipboard
}
},
}
- 使用
<button type="button" v-clipboard:copy="text" v-clipboard:success="clipboardSuccess">
Copy!
</button>
// 可选,可设置统一默认值
clipboardSuccess() {
this.$message({
message: '复制成功',
type: 'success',
duration: 500
});
}
完整代码下载:Clipboard