vue 节流、拖拽指令

请叫我海龟先生 等级 508 2 1

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、后面就是指令解绑了

收藏
评论区

相关推荐

教你用200行代码写一个爱豆拼拼乐H5小游戏(附源码)
前言 本文将带大家一步步实现一个H5拼图小游戏,考虑到H5游戏的轻量级和代码体积,我没有使用react或vue这些框架,而采用我自己写的dom库和原生javascript来实现业务功能,具体库代码可见我的文章如何用不到200行代码写一款属于自己的js类库(https://juejin.im/post/6844903880707293198),构建工具我采
vue-toy: 200行代码模拟Vue实现
vuetoy 200行左右代码模拟vue实现,视图渲染部分使用React来代替Sanbbdom,欢迎Star。 项目地址:https://github.com/bplok20010/vuetoy(https://github.com/bplok20010/vuetoy) codesandbox示例(https://codes
What the f*ck JavaScript?
What the fck JavaScript? 一个有趣和棘手的 JavaScript 示例列表。 JavaScript 是一种很好的语言。
Vue3 的 15 个常用 API
来自公众号:前端印象 本文会频繁地对比Vue2来介绍Vue3,也将对各个API结合代码实例讲解,这既是对自己知识的总结,也希望能帮助到大家 一、前言 大家都知道,现在Vue3的各个版本已经陆续发布了,并且有很多的团队已经着手各个库的开发与Vue2向Vue3的升级,我们当然也不能落后,所以赶紧将你手中的Vue2升级到Vue3,跟着本文一起学
基于Vue实现一个有点意思的拼拼乐小游戏
笔者去年曾写过一个类似的拼拼乐小游戏,技术栈采用自己的Xuery框架和原生javascript实现的,脚手架采用gulp来实现,为了满足对vue的需求,笔者再次使用vue生态将其重构,脚手架采用比较火的vuecli。 前言 为了加深大家对vue的了解和vue项目实战,笔者采用vue生态来重构此项目,方便大家学习和探索。技术栈如下: vuecli4
vue实现世界疫情地图(点击进入子地图)
点击进入子地图目前只实现了中国模块 数据来源,腾讯实时疫情(https://news.qq.com/zt2020/page/feiyan.htm/global),中国疫情网(https://www.ncovchina.com/data.html) 原本只想做中国模块,后来想了想,做个世界的吧 使用axios和echarts,elementui的
前端 滚动到目标元素位置 VUE 版本
1、前言 想起之前一次在写一个小程序商城时候,详情页的类似锚点的跳转花了我不少时间,因为刚写,对小程序滚动,滚动距离那套不熟悉加之本身对什么滚动高度,元素距离顶部距离不是很了解,花了挺长时间的,这几天有空,就研究了下。 2、先看效果 在这里插入图片描述(https://imghelloworld.osscnbeijing.aliyuncs.c
基于Vue3+TypeScript+ Vue-Cli4.0构建手机端模板脚手架
vue3h5template基于 Vue3TypeScript VueCli4.0 vant ui sass rem 适配方案axios 封装 jssdk 配置 vconsole 移动端调试,构建手机端模板脚手架项目地址: 建议手机端查看 Node 版本要求Vue CLI 需要 Node.js 8.9 或更高版本
有关CSS预编译、管理工具和网络安全的相关面试题
我经常会听到一些想入行前端的人问,前端开发需要学习哪些技术?其实,除了核心的HTML、CSS、JavaScript技术外,像CSS预编译、前端框架,如Vue,React、Node、Angular;代码管理工具,如git,代码编辑器,sublime text,还有测试,网络安全等相关技术也是需要会一些。当然要求可能不会那么高,但至少要懂一些。所有今天准备了一些
vue-生命周期
vue生命周期 即为一个组件从出生到死亡的一个完整周期,主要包括以下4个阶段:创建,挂载,更新,销毁 创建前:beforeCreate, 创建后:created 挂载前:beforeMount, 挂载后:mounted 更新前:beforeUpdate, 更新后:updated 销毁前:beforeDestroy, 销毁后:destroye
浅谈Vue.js
作为一名Vue.js的忠实用户,我想有必要写点文章来歌颂这一门美好的语言了,我给它的总体评价是“简单却不失优雅,小巧而不乏大匠”,下面将围绕这句话给大家介绍Vue.js,希望能够激发你对Vue.js的兴趣。 注:本文介绍的是Vue1.×,目前Vue已经升级至2.×,功能和语法上有一定升级和修改,想了解2.×的请移步:Vue.js简介
11个基于vue的UI框架_U.R.M.L
Element UI 来自中国,由与 Mint UI 相同的开发者所创建。Element UI 是用于 Web 和桌面应用程序的桌面 UI 工具包,如果你需要开发 Electron 应用,这个库会是你的理想之选。 iView 是一个 UI 工具包,其中包含简洁又设计优雅的小部件和各种组件。iView 团队维护非常及时,最近一次的更新在19年3
Vue进阶(四十七):面试必备:2021 Vue经典面试题总结(含答案)_IT全栈 华强工作室
面试必备:2021 Vue经典面试题总结(含答案)一、什么是MVVM?
前端培训-Vue专题之Vue基础
简介特点:MVVM框架,双向绑定,数据驱动,单页面,组件化。 区别Vue 和 jQuery 的区别:不直接操作DOM,而是操作数据。案例:Hello World 你好,世界HTML代码:xml<h1msg</h1jQuery实现javascript$("h1").text("你好,世界");Vue 实现javascriptthis.msg '你好,世界'
webpack5手撸vue2脚手架
webpack5手撸vue相信工作个12年的小伙伴们在面试的时候多多少少怕被问到关于webpack方面的知识,本菜鸟最近闲来无事,就尝试了手撸了下vue2的脚手架,第一次发帖实在是没有经验,望海涵。 language JavaScript "name": "vuecliversion2", "version": "1.0.0", "desc