vue自定义tap指令及tap事件的实现


Posted in Javascript onSeptember 18, 2018

1.Vue指令

Vue提供自定义实现指令的功能, 和组件类似,可以是全局指令和局部指令,详细可以参见vue官网自定义指令一节(https://cn.vuejs.org/v2/guide/custom-directive.html).

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:https://github.com/weijhfly/vue-tap

参考了其他vue-tap插件,但仍有需要完善的地方,后续更新。此外,在移动端解决点击延迟问题,还是比较推荐fastclick,兼容性较好且方便使用,不过相对而言模拟tap事件体积较小,也可以拿来练手了。

总结

以上所述是小编给大家介绍的vue自定义tap指令及tap事件的实现,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
JavaScript 异步调用框架 (Part 2 - 用例设计)
Aug 03 Javascript
JavaScript 以对象为索引的关联数组
May 19 Javascript
JavaScript 原型链学习总结
Oct 29 Javascript
jQuery中创建实例与原型继承揭秘
Dec 21 Javascript
js中事件的处理与浏览器对象示例介绍
Nov 29 Javascript
判断文件是否正在被使用的JS代码
Dec 21 Javascript
js实现可兼容IE、FF、Chrome、Opera及Safari的音乐播放器
Feb 11 Javascript
javascript中传统事件与现代事件
Jun 23 Javascript
JS求Number类型数组中最大元素方法
Apr 08 Javascript
深入Vue-Router路由嵌套理解
Aug 13 Javascript
js利用递归与promise 按顺序请求数据的方法
Aug 30 Javascript
如何利用vue实现波谱拟合详解
Nov 05 Javascript
Vue条件循环判断+计算属性+绑定样式v-bind的实例
Sep 18 #Javascript
浅谈vue同一页面中拥有两个表单时,的验证问题
Sep 18 #Javascript
记React connect的几种写法(小结)
Sep 18 #Javascript
Vue循环组件加validate多表单验证的实例
Sep 18 #Javascript
vue2.0 + ele的循环表单及验证字段方法
Sep 18 #Javascript
JavaScript指定断点操作实例教程
Sep 18 #Javascript
对VUE中的对象添加属性
Sep 18 #Javascript
You might like
Linux下将excel数据导入到mssql数据库中的方法
2010/02/08 PHP
Mysql中分页查询的两个解决方法比较
2013/05/02 PHP
PHP使用Session遇到的一个Permission denied Notice解决办法
2014/07/30 PHP
推荐10个提供免费PHP脚本下载的网站
2014/12/31 PHP
PHP常用函数之根据生日计算年龄功能示例
2019/10/21 PHP
php使用fputcsv实现大数据的导出操作详解
2020/02/27 PHP
小议Function.apply()之二------利用Apply的参数数组化来提高 JavaScript程序性能
2006/11/30 Javascript
用JS实现的一个include函数
2007/07/21 Javascript
ASP Json Parser修正版
2009/12/06 Javascript
基于jquery实现漂亮的动态信息提示效果
2011/08/02 Javascript
Jquery的hide及toggle方法让超链接慢慢消失
2013/09/06 Javascript
javascript将url中的参数加密解密代码
2014/11/17 Javascript
jQuery中eq()方法用法实例
2015/01/05 Javascript
jQuery自定义数值抽奖活动代码
2016/06/11 Javascript
微信小程序表单弹窗实例
2018/07/19 Javascript
基于jquery实现九宫格拼图小游戏
2018/11/30 jQuery
webpack配置proxyTable时pathRewrite无效的解决方法
2018/12/13 Javascript
vue点击按钮实现简单页面的切换
2020/09/08 Javascript
[04:03]DOTA2英雄梦之声_第02期_风暴之灵
2014/06/30 DOTA
[43:24]VG vs Serenity 2018国际邀请赛小组赛BO2 第二场 8.17
2018/08/20 DOTA
Python语法快速入门指南
2015/10/12 Python
PyQt实现界面翻转切换效果
2018/04/20 Python
Python绘图实现显示中文
2019/12/04 Python
Python 窗体(tkinter)下拉列表框(Combobox)实例
2020/03/04 Python
美国网上眼镜供应商:LEOTONY(眼镜、RX太阳镜和太阳镜)
2017/10/31 全球购物
应届大专毕业生个人自荐信
2013/09/22 职场文书
高中生学习生活的自我评价
2013/10/09 职场文书
英语系毕业生自荐信
2013/10/31 职场文书
会计专业求职信范文
2014/03/16 职场文书
中班上学期幼儿评语
2014/04/30 职场文书
贷款委托书怎么写
2014/08/02 职场文书
2015年图书馆个人工作总结
2015/05/26 职场文书
2019年幼儿园家长接送责任书
2019/10/29 职场文书
MySQL中utf8mb4排序规则示例
2021/08/02 MySQL
浅谈GO中的Channel以及死锁的造成
2022/03/18 Golang
mongoDB数据库索引快速入门指南
2022/03/23 MongoDB