vue 节流、拖拽指令

1、在开发中时长遇到按钮重复点击或者多次点击的情况

比如创建订单或者其他情况,当然也可以通过设置变量开关,禁止状态,这里就分享一个 节流的指令

VUE3好像指令的生命周期和组件的生命周期同步了
//立即执行版本,点击后会执行一次,然后进入定时器
export const throttle = {
	inserted: function(el, binding) {
		let timer = null
		el.addEventListener('click', handClick, false)
		function handClick() {
			if (timer) {
				return
			}
			// 当指令传参时 
			let arg = binding.arg
			binding.value(arg)
			timer = setTimeout(() => {
				clearTimeout(timer)
				timer = null
			}, 2000)
		}
		el._handClick_ = handClick
	},
	unbind: function(el) {
		//销毁时 清除事件
		if (el._handClick_) {
			el.removeEventListener('click', el._handClick_, false)
			el._handClick_ = null
			delete el._handClick_
		}
	}
}

2、使用 注册就不写了

<div v-throttle:1="toHandle" ></div>
	v-throttle:1 是传了个参数,当然可以不传 v-throttle="toHandle"
	v-throttle="toHandle(1)",这种写法是绑定了个表达式,不是函数

2、拖拽指令

export const drag = {
	inserted: function(el, binding) {
		const willChange = getComputedStyle(el).willChange
    	const position = getComputedStyle(el).position
		const transform = getComputedStyle(el).transform

        // 盒子宽高
		let width = el.offsetWidth
		let height = el.offsetHeight
	
        // 设备 宽高 getPageX,getPageY 为设备宽高
		let pageWidth = getPageX()
		let pageHeight = getPageY()
        // 记录手指按下位置
		let dX,dY
		
		if (['absolute', 'fixed'].indexOf(position) === -1) {
			el.style.position = 'absolute'
		}

		el.style.willChange =
		willChange === 'auto' ? 'left,top' : `${willChange},left,top`
  
	  	el.style.transform =
		transform === 'none' ? 'translateZ(0)' : `${transform} translateZ(0)`
        
        function start(e) {
            let box = el.getBoundingClientRect()
            let touchMsg = e.changedTouches[0]
            dX = touchMsg.pageX - box.left
			dY = touchMsg.pageY - box.top

			el.addEventListener('touchmove',move, false)
			el.addEventListener('touchcancel',cancel, false)
        }

        function move(eMove) {
            let moveMsg = eMove.changedTouches[0]
            let top = moveMsg.pageY - dY
            let left = moveMsg.pageX - dX
            // 边界值限定
			let maxLeft = pageWidth - width
			let maxTop = pageHeight - height

            el.style.top =  top > maxTop ? maxTop + 'px' : (top > 1 ? top + 'px' : '0px')
			el.style.left = left > maxLeft ? maxLeft + 'px' : (left > 1 ? left + 'px' : '0px')
			
            eMove.preventDefault()
		}
		function cancel() {
			el.removeEventListener('touchstart',start, false)
			el.removeEventListener('touchmove',move, false)
			el.removeEventListener('touchcancel',cancel, false)
		}
	   
		el.addEventListener('touchstart',start,false)
		el.__dragTouchstartHandler__ = start
	},
	unbind: function(el) {
		if (el.__dragTouchstartHandler__) {
			el.removeEventListener('touchstart', el.__dragTouchstartHandler__, false)
			el.__dragTouchstartHandler__ = null
			delete el.__dragTouchstartHandler__
        }
       
	}
}

整体思路:
1、移动端并没有手指按下点到父元素的距离(offsetTop),只有距离页面的 X,Y,所以 用按下点到页面的距离 - 元素距离顶部距离 = 按下点到父元素距离
2、移动时、用移动点位距离 - 按下点到父元素距离 = 定位位置
3、最后 preventDefault()阻止默认行为
4、后面就是指令解绑了

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值