vue自定义指令实现v-tap插件


Posted in Javascript onNovember 03, 2016

放弃jQuery,拥抱MVVM,拥抱组件吧!

vue-touch基于hammer,对于普通简单手势的页面来说过于庞大!
于是想自己实现一个最常用的手势tap。顺着自定义指令和插件文档,昨晚实现了一个v-tap指令,丢出这篇干货。

指令与插件介绍
自定义指令和插件官方文档中也介绍比较简单详细,就不过多介绍。
我先说下本插件就用了三个API,如果大家不了解最好先事先看下文档避免后面的代码看的迷糊。

指令部分
1.update(nVal,oVal)
2.acceptStatement

插件部分
Vue.use()

接着我们需要像写jQuery插件一样学习写Vue插件的格式。

继续官方文档

MyPlugin.install = function (Vue, options) {
 // 1. 添加全局方法或属性
 Vue.myGlobalMethod = ...
 // 2. 添加全局资源
 Vue.directive('my-directive', {})
 // 3. 添加实例方法
 Vue.prototype.$myMethod = ...
}

是不是看的还不太明白?那我们可以直接看作者的插件代码。

;(function () {

 var vueTouch = {}

 vueTouch.install = function (Vue) {

 Vue.directive('touch', {

  isFn: true,
  acceptStatement: true,

  bind: function () {

  },

  update: function (fn) {

  },

  unbind: function () {

  }
 })
 }

 if (typeof exports == "object") {
 module.exports = vueTouch
 } else if (typeof define == "function" && define.amd) {
 define([], function(){ return vueTouch })
 } else if (window.Vue) {
 window.VueTouch = vueTouch
 Vue.use(vueTouch)
 }

})()

我把多余无关代码都删除了,可以发现其实格式就是如此,剩下的就是利用我们自己js的功底直接编写即可。
PS:关于 isFn:true 这个属性,我在文档中没有查到相关信息,个人认为可能是一种注释,代表这个指令是需要fn的expression(这个是指令的表达式,详见指令实例属性)。

Just do it

首先,按照插件格式先写好外层。

;(function() {
 var vueTap = {};
 vueTap.install = function(Vue) {

 };

 if (typeof exports == "object") {
  module.exports = vueTap;
 } else if (typeof define == "function" && define.amd) {
  define([], function(){ return vueTap })
 } else if (window.Vue) {
  window.vueTap = vueTap;
  Vue.use(vueTap);
 }

})();

接着在我们的 vueTap.install 里写我们自己的自定义指令

Vue.directive('tap', {
  isFn : true,
  bind : function() {

  },
  update : function(fn) {

  },
  unbind : function() {},
  isTap : function() {
   //判断是否为tap
  },
  touchstart : function(e,self) {

  },
  touchend : function(e,self) {

  }
 });
};

由于只有update才有参数可传,可以接收到我们expression,于是我把事件绑定处理过程都写在了update里。

PS: 当然也有小伙伴喜欢在这把fn都赋予在this(这里的this是directve实例)上,最后在bind的地方绑定事件。这个我并没有找到规范,还不知道写哪比较好。

update : function(fn) {
 var self = this; //存下this,方便以后用
  //在directive上绑定的属性和方法
  //都可通过self.xxx self.touchstart()获取
  self.tapObj = {}; //初始化我们的tap对象

 if(typeof fn !== 'function') {
 //你别给我搞事!
  return console.error('The param of directive "v-tap" must be a function!');
 }

 self.handler = function(e) { //给当前directive存个handler方便之后调用
  e.tapObj = self.tapObj; 
  //把我们的tap对象赋值给原生event对象上,方便回调里获取参数
  fn.call(self,e);
 };

 //把我们的start和end剥离出来,写在directive上
 //由于只有tap事件,所以我们在move过程就不需要做处理
 this.el.addEventListener('touchstart',function(e) {
  self.touchstart(e,self);
 },false);

 this.el.addEventListener('touchend',function(e) {
  self.touchend(e,self,fn);
 },false);

}

在update很简单,就是一些初始化,事件绑定和给实例赋值的过程。
最后就是isTap,touchstart,touchend的逻辑处理。

isTap : function() {
 var tapObj = this.tapObj;
 return this.time < 150 && Math.abs(tapObj.distanceX) < 2 && Math.abs(tapObj.distanceY) < 2;
},
touchstart : function(e,self) {
 var touches = e.touches[0];
 var tapObj = self.tapObj;
 tapObj.pageX = touches.pageX;
 tapObj.pageY = touches.pageY;
 tapObj.clientX = touches.clientX;
 tapObj.clientY = touches.clientY;
 self.time = +new Date();
},
touchend : function(e,self) {
 var touches = e.changedTouches[0];
 var tapObj = self.tapObj;
 self.time = +new Date() - self.time;
 tapObj.distanceX = tapObj.pageX - touches.pageX;
 tapObj.distanceY = tapObj.pageY - touches.pageY;

 if (self.isTap(tapObj))
  self.handler(e);
}

最后有个大问题,如何能让我们的expression可接受传参?

<ul>
 <li v-for="el in list"
  v-tap="args($index,el,$event)"
   >
  {{el.name}}---{{el.age}}
 </li>
</ul>

那就要在我们的directive上加一个属性acceptStatement:true(详见文档acceptStatement)

总结
写了这个v-tap插件几个心得分享给大家。
1.在update里的this指向是directive实例,而不是vm,也不是dom
2.在directive('name',{}) 对象里可自定义属性和方法。调用就是self.xxx
3.开启自定义指令接受内联语句 acceptStatement:true
4.最后的接口别忘了 Vue.use(obj)
我这里没有对v-tap.stop, v-tap.prevent,v-tap.stop.prevent做处理,大家可以自己实现!也灰常简单。
(我之后会对v-tap进行补充)

最后丢出github地址: https://github.com/MeCKodo/vue-tap

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
Javascript实例教程(19) 使用HoTMetal(2)
Dec 23 Javascript
JQuery的$命名冲突详细解析
Dec 28 Javascript
Javascript Object 对象学习笔记
Dec 17 Javascript
js实现的tab标签切换效果代码分享
Aug 25 Javascript
jQuery简单实现input文本框内灰色提示文本效果的方法
Dec 02 Javascript
Javascript函数中的arguments.callee用法实例分析
Sep 16 Javascript
浅谈jquery中使用canvas的问题
Oct 10 Javascript
Angular4表单验证代码详解
Sep 03 Javascript
highcharts 在angular中的使用示例代码
Sep 20 Javascript
不到200行 JavaScript 代码实现富文本编辑器的方法
Jan 03 Javascript
vuejs2.0运用原生js实现简单拖拽元素功能
Aug 21 Javascript
vue项目移动端实现ip输入框问题
Mar 19 Javascript
angular ngClick阻止冒泡使用默认行为的方法
Nov 03 #Javascript
vue.js指令v-for使用及索引获取
Nov 03 #Javascript
vue.js初学入门教程(1)
Nov 03 #Javascript
把json格式的字符串转换成javascript对象或数组的方法总结
Nov 03 #Javascript
AngularJS出现$http异步后台无法获取请求参数问题的解决方法
Nov 03 #Javascript
Centos7 中安装 Node.js v4.4.4
Nov 03 #Javascript
[原创]javascript typeof id==='string'?document.getElementById(id):id解释
Nov 02 #Javascript
You might like
PHP VS ASP
2006/10/09 PHP
把1316这个数表示成两个数的和,其中一个为13的倍数,另一个是11的倍数,求这两个数。
2011/06/24 PHP
通过缓存数据库结果提高PHP性能的原理介绍
2012/09/05 PHP
盘点PHP和ASP.NET的10大对比!
2015/12/24 PHP
php基于PDO连接MSSQL示例DEMO
2016/07/13 PHP
PHP-CGI远程代码执行漏洞分析与防范
2017/05/07 PHP
php表单处理操作
2017/11/16 PHP
jQuery 打造动态渐变按钮 详细图文教程
2010/04/25 Javascript
javascript 获取函数形参个数
2014/07/31 Javascript
jquery中表单 多选框的一种巧妙写法
2015/09/06 Javascript
QQ登录背景闪动效果附效果演示源码下载
2015/09/22 Javascript
详解Webwork中Action 调用的方法
2016/02/02 Javascript
ES6所改良的javascript“缺陷”问题
2016/08/23 Javascript
使用ionic切换页面卡顿的解决方法
2016/12/16 Javascript
微信小程序 跳转传递数据的实例
2017/07/06 Javascript
jQuery中将json数据显示到页面表格的方法
2018/05/27 jQuery
Puppet的一些技巧
2018/09/17 Javascript
webpack开发环境和生产环境的深入理解
2018/11/08 Javascript
简单的React SSR服务器渲染实现
2018/12/11 Javascript
Python面向对象之接口、抽象类与多态详解
2018/08/27 Python
Python多线程处理实例详解【单进程/多进程】
2019/01/30 Python
Pytorch中的自动求梯度机制和Variable类实例
2020/02/29 Python
Python+OpenCV图像处理——图像二值化的实现
2020/10/24 Python
python链表类中获取元素实例方法
2021/02/23 Python
CSS3绘制不规则图形的一些方法示例
2015/11/07 HTML / CSS
html5 Canvas绘制线条 closePath()实例代码
2012/05/10 HTML / CSS
css 如何让背景图片拉伸填充避免重复显示
2013/07/11 HTML / CSS
微软英国官方网站:Microsoft英国
2016/10/15 全球购物
打架检讨书800字
2014/01/10 职场文书
军训教官感言
2014/03/02 职场文书
《郑和远航》教学反思
2014/04/16 职场文书
质量保证书范本
2014/04/29 职场文书
机械专业技术员求职信
2014/06/14 职场文书
大学生考试作弊被抓检讨书
2014/12/27 职场文书
2015年教师节演讲稿范文
2015/03/19 职场文书
2016元旦晚会主持人开场白和结束语
2015/12/03 职场文书