vue自定义tap指令及tap事件的实现
1.vue指令
vue提供自定义实现指令的功能, 和组件类似,可以是全局指令和局部指令,详细可以参见vue官网自定义指令一节().
2.v-tap指令实现
我个人的理解,编写指令即是在vue指令对象提供的钩子函数中做相应的逻辑处理,tap指令是在bind钩子函数中做相应的处理, 首先,要明白的是tap是为了处理click事件在iphone上的存在300ms的延时,这样使得连续点击很不流畅,tap通过移动端的touchstart事件和touchend事件判断移动距离为零的话,则触发绑定的函数,话不多说,上代码:
vue.directive('tap',{ bind(el, binding, vnode){ let expression = binding.value; let handler = expression.name; let args = expression.args on(el, 'touchstart', (e)=>{ let startx = e.changedtouches[0].clientx; let starty = e.changedtouches[0].clienty; once(el, 'touchend',(ev)=>{ let disx = math.abs(ev.changedtouches[0].clientx-startx); let disy = math.abs(ev.changedtouches[0].clienty-starty); if(disx == 0 && disy ==0){ handler(args); } }) }) } })
使用示例: <div v-tap="{ name : mymethod, args:{arg1:11, args2:22} }"></div>
3.总结
当我们需要复用一些dom底层操作的时候,可以考虑使用vue directive的方式复用代码.
下面看下vue tap事件的实现代码
前两天做了个tap.js插件,实现了移动端touch事件模拟click事件,解决点击延迟的问题,但是在vue中并不能用v-tap来调用,所以今天做了vue版的vue-tap.js。此前也曾用过其他的插件来实现v-tap,但方式仍有些累赘,于是便用了更简洁的方式来实现,下面附上代码(只支持vue2.0+)。
vue-tap.js
/*! * vue-tap.js * by weijianhua https://github.com/weijhfly/vue-tap */ ;(function (factory) { if (typeof define === 'function' && define.amd) { define(function(){return factory;}); }else if (typeof exports == "object") { module.exports = factory; }else{ vue.use(factory); } }({ master:{ bind: function (el, binding) { var istouch = "ontouchend" in document; el.exec = function (e) { var data = binding.value; data[0].apply(this, data.slice(1)); }; if (istouch) { //touchstart el.addeventlistener('touchstart', function (e) { binding.modifiers.stop && (e.stoppropagation()); var t = e.touches[0]; el.startx = t.clientx; el.starty = t.clienty; el.stime = + new date; }); //touchend el.addeventlistener('touchend', function (e) { binding.modifiers.stop && (e.stoppropagation()); var t = e.changedtouches[0]; el.endx = t.clientx; el.endy = t.clienty; if((+ new date)-el.stime<300){ if(math.abs(el.endx-el.startx)+math.abs(el.endy-el.starty)<20){ e.preventdefault(); el.exec(); } } }); }else { //click el.addeventlistener('click', function (e) { binding.modifiers.stop && (e.stoppropagation()); el.exec(); }); } }, componentupdated : function(el,binding) { el.exec = function () { var data = binding.value; data[0].apply(this, data.slice(1)); }; }, unbind: function (el) { el.exec = null; } }, install:function(){ vue.directive('tap', this.master); } }))
demo.html
<!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1,maximum-scale=1.0, user-scalable=0" /> <title>vue plugin test</title> <style type="text/css"> strong{ font-size: 15px; } pre{ padding: 16px 0; overflow: auto; line-height: 1.45; background-color: #f6f8fa; border-radius: 3px; } </style> </head> <body style="padding:30px;"> <div id="app"> <pre> <strong>vue-tap.js</strong> <b>简洁的调用方式:</b> v-tap="[方法,参数一,参数二...]" <b>获取参数:</b> methods:{ tap:function(参数一,参数二...){ console.log(参数一,参数二...); } } <b>阻止冒泡:</b> v-tap.stop </pre> <hr> <div v-for="(l,i) in list"> <div v-tap="[tap,l,i]">li-{{l}}-{{i}}</div> </div> <br> <hr> <div v-tap="[test,'parent']"> parent<br><br> <button v-tap.stop="[test,'son']">stop propagation</button> </div> </div> <script src="https://cdn.bootcss.com/vue/2.5.13/vue.js"></script> <script src="vue-tap.js"></script> <script> new vue({ el:'#app', data:{ list:['a','b','c','e','f'] }, methods:{ tap:function(i,k){ console.log(i,k); }, test:function(i){ console.log(i); } } }) if(window.innerwidth < 768){ document.getelementsbytagname('body')[0].style.padding = 0; } </script> </body> </html>
github:
参考了其他vue-tap插件,但仍有需要完善的地方,后续更新。此外,在移动端解决点击延迟问题,还是比较推荐fastclick,兼容性较好且方便使用,不过相对而言模拟tap事件体积较小,也可以拿来练手了。
总结
以上所述是小编给大家介绍的vue自定义tap指令及tap事件的实现,希望对大家有所帮助
下一篇: js select多选列表传值代码