vue自定义指令-【单击复制】【双击复制】【点击icon复制】
copy.js 文件
/**
* CV指令【单击复制】【双击复制】【点击icon复制】
* @param {?String | ?Number} title - 自定义内容
* @param {?String | 'right'} position - 图标位置
* @param {?Number | 14} size - 图标大小
* @param {Object} binding.value - {title,position,size}
* 直接使用: v-copy & v-copy.dblclick & v-copy.icon & v-copy="{title:'自定义内容'}"
* 配置事件: v-copy="{title:'自定义内容'}"
* 注: position【图标位置】和size【图标大小】只针对v-copy.icon
*/
import {
message
} from 'antd'
export default {
bind(el, binding) {
// 如果不传值,默认使用当前元素的值
el.$value = binding.value?.title ? binding.value.title : el.innerText
// 双击触发复制
if (binding.modifiers.dblclick) {
el.addEventListener('dblclick', () => handleClick(textValue))
el.style.cursor = 'pointer'
}
// 点击icon触发复制
else if (binding.modifiers.icon) {
if (el.hasIcon) return
const a = `<a-icon type="copy" style="margin:0 5px;cursor: pointer;font-size:${binding.value?.size}px" ></a-icon>`
// 创建构造器
const tooltip = Vue.extend({
template: a
})
// 创建一个 tooltip 实例并返回 dom 节点
const component = new tooltip().$mount()
// 复制icon是添加在元素左边还是右边,默认是右边
binding.value?.position == 'left' ? el.insertBefore(component.$el, el.childNodes[0]) : el.appendChild(component.$el)
el.hasIcon = true
component.$el.addEventListener('click', () => handleClick(textValue))
// 注册鼠标进入事件,设置其颜色为蓝色
component.$el.addEventListener('mouseover', () => component.$el.style.color = "#2475fc")
// 注册鼠标离开事件,恢复到这个标签默认的颜色
component.$el.addEventListener('mouseout', () => component.$el.style.color = "")
}
// 单击触发复制
else {
el.addEventListener('click', () => handleClick(el.$value))
el.style.cursor = 'pointer'
}
},
// 当传进来的值更新的时候触发
componentUpdated(el, binding) {
el.$value = binding.value?.title;
},
// 指令与元素解绑的时候,移除事件绑定
unbind(el) {
el.removeEventListener('click', handleClick);
},
}
function handleClick(text) {
// 创建元素
if (!document.getElementById('copyTarget')) {
const copyTarget = document.createElement('input')
copyTarget.setAttribute('style', 'position:fixed;top:0;left:0;opacity:0;z-index:-1000;')
copyTarget.setAttribute('id', 'copyTarget')
document.body.appendChild(copyTarget)
}
// 复制内容
const input = document.getElementById('copyTarget')
input.value = text
input.select()
document.execCommand('copy')
message.success('复制成功')
}
过程中遇到过一个问题:
在元素解除绑定的时候又调用了一次复制事件的方法。
绑定事件:el.addEventListener('click', () => handleClick(el.$value))
解除绑定:
1、el.removeEventListener('click', handleClick(el.$value));
2、el.removeEventListener('click', handleClick);
在绑定事件时,如果要传递参数给事件处理函数,可以使用箭头函数来创建一个匿名函数,并在其中调用处理函数,并传递所需的参数。例如:el.addEventListener('click', () => handleClick(el.$value))。
现在,要解除绑定该事件,有两种方法可以实现:
el.removeEventListener('click', handleClick(el.$value));
这种方法将尝试移除与指定参数匹配的特定事件处理函数。但是这种方法是错误的,因为它传递了一个函数调用,而不是函数本身。因此,这种方式不能正确解除绑定。
el.removeEventListener('click', handleClick);
这种方法将移除与指定函数名称匹配的事件处理函数。在绑定事件时,我们使用的是相同的函数名称,因此可以使用该函数名称将事件处理函数正确地解除绑定。
所以,正确的解除绑定方法是第二种方式:el.removeEventListener('click', handleClick);