vue2指令

文章介绍了如何在Vue中实现文本的单击、双击和图标触发的一键复制功能,以及如何使用动画实现文字无缝滚动和点击外部元素触发事件的组件。还涉及了正则表达式验证输入框内容的示例。
摘要由CSDN通过智能技术生成

v-copy(一键复制)

需求:实现一键复制文本内容,用于鼠标右键粘贴。
思路:
1、动态创建 textarea 标签,并设置 readOnly 属性及移出可视区域
2、将要复制的值赋给 textarea 标签的 value 属性,并插入到 body
3、选中值 textarea 并复制
4、将 body 中插入的 textarea 移除
5、在第一次调用时绑定事件,在解绑时移除事件

const copy = {
  bind(el, binding) {
    // 双击触发复制
    if (binding.modifiers.dblclick) {
      el.addEventListener('dblclick', () => handleClick(el.innerText))
      el.style.cursor = 'copy'
    } else if (binding.modifiers.icon) {
      // 点击icon触发复制
      if (el.hasIcon) return
      const iconElement = document.createElement('i')
      iconElement.setAttribute('class', 'el-icon-document-copy')
      iconElement.setAttribute('style', 'margin-left:5px')
      el.appendChild(iconElement)
      el.hasIcon = true
      iconElement.addEventListener('click', () => handleClick(el.innerText))
      iconElement.style.cursor = 'copy'
    } else {
      // 单击触发复制
      el.addEventListener('click', () => handleClick(el.innerText))
      el.style.cursor = 'copy'
    }
  },
}

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')
  // alert('复制成功')
}
export default copy

使用:给 Dom 加上 v-copy 及复制的文本即可

<div v-copy> 单击复制 </div>
<div v-copy.dblclick> 双击复制 </div>
<div v-copy.icon> icon复制 </div>

v-textRoll(文字溢出滚动)

需求:实现文字在指定宽度的元素中无缝滚动,绑定参数可实现控制滚动速度

export default {
  inserted: (el, binding, vNode) => {
    el.style.overflow = 'hidden'
    el.style.whiteSpace = 'nowrap'
    const speed = binding.value || 60
    el.__text__ = `${vNode.children[0].text.trim()}`
    el.__span__ = document.createElement('span')
    el.__span__.innerHTML = el.__text__
    el.__span__.style.display = 'inline-block'
    el.innerHTML = ''
    el.appendChild(el.__span__)
    el.__spanWidth__ = el.__span__.offsetWidth
    el.isRoll = () => {
      if (el.__spanWidth__ > el.offsetWidth) {
        const times = binding.value || Math.max(Number(2 * el.__span__.offsetWidth - el.offsetWidth) / speed, 8)
        el.__span__.style.animation = `roll-text linear ${times}s normal infinite`
        el.__span__.innerHTML = `${el.__text__}&nbsp;&nbsp;&nbsp;&nbsp;${el.__text__}&nbsp;&nbsp;&nbsp;&nbsp;`
      } else {
        el.__span__.style.animation = 'none'
        el.__span__.innerHTML = `${el.__text__}`
      }
    }
    el.__observe__ = new ResizeObserver(el.isRoll)
    el.__observe__.observe(el, { box: 'border-box' })
  },
  componentUpdated(el, _, vNode) {
    el.__text__ = `${vNode.children[0].text.trim()}`
    el.__span__.innerHTML = el.__text__
    el.innerHTML = ''
    el.appendChild(el.__span__)
    el.__spanWidth__ = el.__span__.offsetWidth
    el.isRoll()
  },
  unbind: el => {
    el.__observe__.disconnect()
  },
}

需要配合动画样式实现

//文字滚动使用动画
@keyframes roll-text {
  0% {
    transform: translate3d(0%, 0, 0);
  }
  100% {
    transform: translate3d(-50%, 0, 0);
  }
}

v-clickOutside(点击外部触发)

需求:实现点击除设置指令的元素外部即可触发

参数:需要执行的方法

export default {
  bind(el, binding, vnode) {
    function documentHandler(e) {
      // 这里判断点击的元素是否是本身,是本身,则返回
      if (el.contains(e.target)) {
        return false
      }
      // 判断指令中是否绑定了函数
      if (binding && binding.expression) {
        // 如果绑定了函数 则调用那个函数,此处binding.value就是handleClose方法
        if (binding.value && binding.value(e)) {
          binding.value(e)
        }
      }
    }
    // 给当前元素绑定个私有变量,方便在unbind中可以解除事件监听
    el.__vueClickOutside__ = documentHandler
    document.addEventListener('click', documentHandler)
  },
  unbind(el, binding) {
    // 解除事件监听
    document.removeEventListener('click', el.__vueClickOutside__)
    delete el.__vueClickOutside__
  },
}

v-inputRule (限制输入框指定正则数据)

需求:输入框内容不满足输入的正则自动触发删除本次输入

// 正则规则可根据需求自定义

let findEle = (parent, type) => {
  return parent.tagName.toLowerCase() === type ? parent : parent.querySelector(type)
}

function isRegex(param) {
  return param instanceof RegExp
}

const trigger = (el, type) => {
  const e = new Event(type, { bubbles: true, cancelable: true })
  el.dispatchEvent(e)
}

const inputRule = {
  bind: function (el, binding, vnode) {
    el.regRule = binding.value
    el.$inp = findEle(el, 'input')
    el.$inp.handle = () => {
      let value = el.$inp.value
      if (value && isRegex(el.regRule)) {
        const splits = value.match(el.regRule)
        el.$inp.value = splits && splits.length ? splits[0] : ''
      }
      trigger(el.$inp, 'input')
    }
    el.$inp.handleBlur = () => {
      let value = el.$inp.value
      if (value && isRegex(el.regRule)) {
        const splits = value.match(el.regRule)
        el.$inp.value = splits && splits.length ? splits[0] : ''
      }
      trigger(el.$inp, 'input')
    }
    el.$inp.addEventListener('keyup', el.$inp.handle)
    el.$inp.addEventListener('blur', el.$inp.handleBlur)
  },
  unbind: function (el) {
    el.$inp.removeEventListener('keyup', el.$inp.handle)
    el.$inp.removeEventListener('blur', el.$inp.handleBlur)
  },
}

export default inputRule

常用正则:

正整数:/\d+/
负整数:/^-[1-9]\d*$/
大写英文字母:/^[A-Z]+$/
N位小数:new RegExp(`(^-)?\\d+(\\.\\d{0,${n}})?`)
 

  • 9
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vue.js 2中,自定义指令是一种扩展Vue实例功能的方式。根据引用,自定义指令可以分为组件私有自定义指令和项目全局自定义指令。组件私有自定义指令仅在特定组件中可用,而项目全局自定义指令可以在整个项目中使用。 自定义指令的定义方式与过滤器的定义方式类似。可以通过在Vue实例的directives选项中定义指令或在组件的directives选项中定义指令。具体的例子如引用所示,在任意组件中使用v-color指令。 在指令的定义中,可以通过bind和update函数来实现指令所需的逻辑。bind函数在指令被绑定到元素时调用,可以进行初始化设置。update函数在指令所在元素的值发生变化时调用,可以响应数据的变化并做出相应的操作,如引用所述。 总结来说,Vue.js 2中的自定义指令是一种可以扩展Vue实例功能的方式,可以在组件私有或项目全局范围内使用。可以通过定义指令和实现相应的逻辑来实现自定义指令功能。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [vue2自定义指令方式](https://blog.csdn.net/qq_40639028/article/details/120145794)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值