vue 节流、拖拽指令

请叫我海龟先生 等级 879 2 1
标签: Javascript

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

收藏
评论区

相关推荐

基于Vue实现一个有点意思的拼拼乐小游戏
笔者去年曾写过一个类似的拼拼乐小游戏,技术栈采用自己的Xuery框架和原生javascript实现的,脚手架采用gulp来实现,为了满足对vue的需求,笔者再次使用vue生态将其重构,脚手架采用比较火的vuecli。 前言 为了加深大家对vue的了解和vue项目实战,笔者采用vue生态来重构此项目,方便大家学习和探索。技术栈如下: vuecli4
前端培训-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
vscode的eslint插件不起作用
最近在用vue进行开发,但是vsCode中的eslint插件装上之后不起作用 1.vsCode打开“设置”,选择"settings.json" ![](https://img2018.cnblogs.com/blog/921637/201905/921637-20190516165707540-1304630667.png) 2.输入一段脚本
Angular React Vue我应该选择什么?
2017 年比较 Angular、React、Vue 三剑客 ============================== 为 web 应用选择 JavaScript 开发框架是一件很费脑筋的事。现如今 [Angular](https://www.oschina.net/action/GoToLink?url=https%3A%2F%2Flink.juej
Authing 新版登录表单组件上线啦
同时支持 **React** 、 **Vue** 、 **Angular** 及 **原生 JavaScript** 命令式调用的 Authing 新版登录表单(即 [Guard2.0](https://www.oschina.net/action/GoToLink?url=https%3A%2F%2Fdocs.authing.cn%2Fsdk%2F
CodeMirror 在线代码编辑器
像百度编辑器插件部分、菜鸟教程示例等高德地图都在使用,这里也记录一下: CodeMirror是一个用于编辑器文本框textarea代码高亮javascript插件......vue 中使用 参见:https://www.npmjs.com/package/vue-codemirrorhttps://blog.csdn.net/oumaharuki/
JavaScript 核心原理精讲【朋友圈已刷屏】
作为一名前端工程师,JavaScript 你一定每天都在用。但是,即便工作 5 年以上的前端也不一定用得非常熟,甚至很多前端对 JavaScript 的掌握程度仅仅停留在会用的层面。 而且 Vue/React 等框架的便利,更是让前端人无需苦学 JavaScript 原生,就可以快速构建一个网页。它解决了开发者短期的痛点,却为依赖框架开发的程序员埋下长期隐
React与Vue的相同与不同点
我们知道JavaScript是世界上最流行的语言之一,React和Vue是JS最流行的两个框架。所以要想前端的开发那么必须掌握好这两个框架。 那么这两个框架有什么不同呢? **React 和 Vue 相同之处,它们都有:** * 使用 Virtual DOM * 提供了响应式 (Reactive) 和组件化 (Composable) 的视图组件
React面试必问Fiber和Hooks,一次搞定
国内的前端领域,Vue 和 React 是最火的两个框架,要说岗位数量,Vue可能会更多一点。 但如果把公司范围缩小到大厂,或者把范围扩展到全球,那React无疑独占鳌头。 ![](https://oscimg.oschina.net/oscnet/ba57134c-6a7d-47d8-a317-7ad3976a1a77.jpg "2019年
Vue 全家桶
vue全家桶。 使用过vue的程序员一般这样评价它,“vue.js兼具angular.js和react.js的优点”。Vue.js 是一个JavaScript MVVM(Model-View-ViewModel)库,用于渐近式构建用户界面。它以数据驱动和组件化思想构建,采用自底向上增量开发的设计思想。相比Angular.js,Vue.js API更加简洁;
Vue 全家桶、原理及优化简议
不少互联网公司都在使用vue技术栈,或称为vue全家桶。 使用过vue的程序员一般这样评价它,“vue.js兼具angular.js和react.js的优点”。Vue.js 是一个JavaScript MVVM(Model-View-ViewModel)库,用于渐近式构建用户界面。它以数据驱动和组件化思想构建,采用自底向上增量开发的设计
vue 路由 懒加载
原文链接: [vue 路由 懒加载](https://my.oschina.net/ahaoboy/blog/1618024) 路由懒加载 ===== 当打包构建应用时,Javascript 包会变得非常大,影响页面加载。如果我们能把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件,这样就更加高效了。 结合 Vue 的[异步组
vue 路由懒加载
原文链接: [vue 路由懒加载](https://my.oschina.net/ahaoboy/blog/1796979) 路由懒加载 ===== 当打包构建应用时,Javascript 包会变得非常大,影响页面加载。如果我们能把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件,这样就更加高效了。 结合 Vue 的[异步组件
阿里巴巴前端练习生学习笔记
字符串引擎和Javascript引擎的区别:是否对于DOM进行全部改变? 相关资料链接• Wiki MVC • Wiki MVVM • Mustach • Handlebars • React • Angular • Vue • Bootstrap • Ant Design • Fusion Des