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);

 

posted @ 2023-07-25 11:49  Private!  阅读(175)  评论(0编辑  收藏  举报