类似于github中代码模块上,有一个复制按钮,复制代码内容的功能。本次封装是基于clip-board:2.0.11版本开发的一键复制指令 效果如下
安装clip-board
npm i clip-board@2.0.11
指令实现代码
import Clipboard from "clipboard";
import { ElMessage } from "element-plus" // 基于自己项目的ui框架引入提示功能
import { Directive, type DirectiveBinding } from "vue" //vue3+ts的写法,如果是vue2也可以不定义类型
import { debounce } from "@pureadmin/utils" // 基于自己项目的防抖函数位置去引入
function copyText(el: string|Element|NodeListOf<Element>): any {
const clipboard = new Clipboard(el)
//clipboard持续性监听复制成功与失败返回
clipboard.on("success", function() {
ElMessage({
message:"复制成功",
type:"success"
})
});
clipboard.on("erroe", function() {
ElMessage({
message:"复制失败",
type:"erroe"
})
});
const styles = {
visibility: "hidden",
minWidth: "24px",
height: "24px",
cursor: "pointer",
padding: "3px",
borderRadius: "4px",
border: "1px solid #e2e4e7",
backgroundColor: "#f6f8fa",
color: "#656d76",
margin: "0 4px",
}
export const copy: Directive = {
created(el: HTMLElement, binding?: DirectiveBinding) {
el.setAttribute("data-clipboard-text", binding.value) // 给对应模块绑定上要复制的内容
const icon = document.createElement("span");
icon.innerHTML = `复制前的svg图标`;
// 给复制功能增加防抖函数
const handleCopy = debounce(
() => {
// 执行复制监听函数并提示复制结果
copyText(el);
icon.innerHTML = `复制成功后的✔svg图标`
setTimeout( () => {
//定时疫苗后再恢复原图标
icon.innerHTML = `复制前的svg图标`;
},1000,true
);
)
//给icon绑定点击事件
icon.onclick = handleCopy;
// 绑定元素样式,让复制按钮始终位于第一排右侧上方
for (const key of Object.keys(styles)) {
icon.style[key] = styles[key];
//有些ts设置的校验规则不一样,可能需要另外一种写法
// ;(icon as any).style[key] = (styles as any)[key]
}
// 模拟hover
icon.onmouseenter = () => {
icon.style.backgroundColor = "#dfdfdf";
}
icon.onmouseleave = () => {
icon.style.backgroundColor = "#f6f8fa";
}
el.style.display = "flex";
el.style.justifyContent = "space-between";
el.style.whiteSpace = "normal";
el.appendChild(icon);
el.onmouseenter = () => {
icon.style.visibility = "visible"
}
el.onmouseleave = () => {
icon.style.visibility = "hidden"
}
}
updated(el: HTMLElement, binding?: DirectiveBinding) {
数据更新的时候重新绑定最新值
el.setAttribute("data-clipboard-text", binding.value)
}
}
指令注册
// 这个项目中我是全局注册的
// main.js
import * as directives from "@/directives";
Object.keys(directives).forEach( key => {
app.directive(key,(directives as {{key:string]: Directive})[key])
})
// 也可以局部引入方法去使用
使用方法
<div v-copy="data.name"></div> 就能够直接复制name里面的值了
其他有趣文章的传送门:
- 初识NODE(从常用模块到小型web服务器构建)
- 一篇学会Array原型里的所有方法
- 一篇掌握Object原型里的所有方法
- 初识Vue3,带你认识Vue2和Vue3的区别(一)
- 妈妈说,不会Vue3会被人看不起的(二)
- 奇怪的原型链冷知识(需要有一定原型链的基础才能看哦)
- vue图片放大器,相册集:vue-photo-preview
- 手摸手教你从0用echart写一个响应式页面
- JS实现URL下载
- 手写Promise,完整实现Promise所有功能