ok 继续回来复习vue指令
给 Dom 加上 v-copy 及复制的文本即可
<template> <button v-copy="copyText">复制</button></template>
<script> export default { data() { return { copyText: 'a copy directives', } }, }</script>
2、v-longpress
需求:
实现长按,用户需要按下并按住按钮几秒钟,触发相应的事件
思路:
- 创建一个计时器, 2 秒后执行函数
- 当用户按下按钮时触发 mousedown 事件,启动计时器;用户松开按钮时调用 mouseout 事件。
- 如果 mouseup 事件 2 秒内被触发,就清除计时器,当作一个普通的点击事件
- 如果计时器没有在 2 秒内清除,则判定为一次长按,可以执行关联的函数。
- 在移动端要考虑 touchstart,touchend 事件
`const longpress = {`` bind: function (el, binding, vNode) { `` if (typeof binding.value !== 'function') { `` throw 'callback must be a function' `` } `` // 定义变量 `` let pressTimer = null `` // 创建计时器( 2秒后执行函数 ) `` let start = (e) => { `` if (e.type === 'click' && e.button !== 0) { `` return `` } `` if (pressTimer === null) { `` pressTimer = setTimeout(() => { `` handler() `` }, 2000) `` } `` } `` // 取消计时器 `` let cancel = (e) => { `` if (pressTimer !== null) { `` clearTimeout(pressTimer) `` pressTimer = null `` } `` } `` // 运行函数 `` const handler = (e) => { `` binding.value(e) `` } `` // 添加事件监听器 `` el.addEventListener('mousedown', start) `` el.addEventListener('touchstart', start) `` // 取消计时器 `` el.addEventListener('click', cancel) `` el.addEventListener('mouseout', cancel) `` el.addEventListener('touchend', cancel) `` el.addEventListener('touchcancel', cancel) `` }, `` // 当传进来的值更新的时候触发 `` componentUpdated(el, { value }) { `` el.$value = value `` }, `` // 指令与元素解绑的时候,移除事件绑定 `` unbind(el) { `` el.removeEventListener('click', el.handler) `` }, ``}``
``export default longpress`
## 3、v-debounce
背景:
在开发中,有些提交保存按钮有时候会在短时间内被点击多次,这样就会多次重复请求后端接口,造成数据的混乱,比如新增表单的提交按钮,多次点击就会新增多条重复的数据。
需求:
防止按钮在短时间内被多次点击,使用防抖函数限制规定时间内只能点击一次。
思路:
- 定义一个延迟执行的方法,如果在延迟时间内再调用该方法,则重新计算执行时间。
- 将时间绑定在 click 方法上。
`const debounce = {`` inserted: function (el, binding) { `` let timer `` el.addEventListener('keyup', () => { `` if (timer) { `` clearTimeout(timer) `` } `` timer = setTimeout(() => { `` binding.value() `` }, 1000) `` }) `` }, ``}``
``export default debounce`
## 4、v-emoji
背景:
开发中遇到的表单输入,往往会有对输入内容的限制,比如不能输入表情和特殊字符,只能输入数字或字母等。
我们常规方法是在每一个表单的 on-change 事件上做处理。
<template> <input type="text" v-model="note" @change="vaidateEmoji" /></template>
<script>
export default {
methods: {
vaidateEmoji() {
var reg = /[^u4E00-u9FA5|d|a-zA-Z|rns,.?!,。?!…—&$=()-+/*{}[]]|s/g this.note = this.note.replace(reg, '') }, }, } </script>
这样代码量比较大而且不好维护,所以我们需要自定义一个指令来解决这问题。
需求:
根据正则表达式,设计自定义处理表单输入规则的指令,下面以禁止输入表情和特殊字符为例。
`let findEle = (parent, type) => {`` return parent.tagName.toLowerCase() === type ? parent : parent.querySelector(type) ``}``
``const trigger = (el, type) => {`` const e = document.createEvent('htmlEvents') `` e.initEvent(type, true, true) `` el.dispatchEvent(e) ``}``
``const emoji = {`` bind: function (el, binding, vnode) { `` // 正则规则可根据需求自定义 `` var regRule = /[^u4E00-u9FA5|d|a-zA-Z|rns,.?!,。?!…—&$=()-+/*{}[]]|s/g `` let $inp = findEle(el, 'input') `` el.$inp = $inp `` $inp.handle = function () { `` let val = $inp.value `` $inp.value = val.replace(regRule, '') ``
``trigger($inp, 'input')`` } `` $inp.addEventListener('keyup', $inp.handle) `` }, `` unbind: function (el) { `` el.$inp.removeEventListener('keyup', el.$inp.handle) `` }, ``}``
``export default emoji`