vue自定义移动端touch事件,点击、滑动、长按事件

用法:

**HTML**
{{ name }}
**js** kim=new Vue({ el:"#app", data:{ name:"开始" }, methods:{ vueTouch:function(s,e){ this.name=s.name; } } });

js核心内容

function vueTouch(el,binding,type){
	var _this=this;
	this.obj=el;
	this.binding=binding;
	this.touchType=type;
	this.vueTouches={x:0,y:0};
	this.vueMoves=true;
	this.vueLeave=true;
	this.longTouch=true;
	this.vueCallBack=typeof(binding.value)=="object"?binding.value.fn:binding.value;
	this.obj.addEventListener("touchstart",function(e){
		_this.start(e);
	},false);
	this.obj.addEventListener("touchend",function(e){
		_this.end(e);
	},false);
	this.obj.addEventListener("touchmove",function(e){
		_this.move(e);
	},false);
};
vueTouch.prototype={
	start:function(e){
		this.vueMoves=true;
		this.vueLeave=true;
		this.longTouch=true;
		this.vueTouches={x:e.changedTouches[0].pageX,y:e.changedTouches[0].pageY};
		this.time=setTimeout(function(){
			if(this.vueLeave&&this.vueMoves){
				this.touchType=="longtap"&&this.vueCallBack(this.binding.value,e);
				this.longTouch=false;
			};
		}.bind(this),1000);
	},
	end:function(e){
		var disX=e.changedTouches[0].pageX-this.vueTouches.x;
		var disY=e.changedTouches[0].pageY-this.vueTouches.y;
		clearTimeout(this.time);
		if(Math.abs(disX)>10||Math.abs(disY)>100){
			this.touchType=="swipe"&&this.vueCallBack(this.binding.value,e);
			if(Math.abs(disX)>Math.abs(disY)){
				if(disX>10){
					this.touchType=="swiperight"&&this.vueCallBack(this.binding.value,e);
				};
				if(disX<-10){
					this.touchType=="swipeleft"&&this.vueCallBack(this.binding.value,e);
				};
			}else{
				if(disY>10){
					this.touchType=="swipedown"&&this.vueCallBack(this.binding.value,e);
				};
				if(disY<-10){
					this.touchType=="swipeup"&&this.vueCallBack(this.binding.value,e);
				};	
			};
		}else{
			if(this.longTouch&&this.vueMoves){
				this.touchType=="tap"&&this.vueCallBack(this.binding.value,e);
				this.vueLeave=false
			};
		};
	},
	move:function(e){
		this.vueMoves=false;
	}
};
Vue.directive("tap",{
	bind:function(el,binding){
		new vueTouch(el,binding,"tap");
	}
});
Vue.directive("swipe",{
	bind:function(el,binding){
		new vueTouch(el,binding,"swipe");
	}
});
Vue.directive("swipeleft",{
	bind:function(el,binding){
		new vueTouch(el,binding,"swipeleft");
	}
});
Vue.directive("swiperight",{
	bind:function(el,binding){
		new vueTouch(el,binding,"swiperight");
	}
});
Vue.directive("swipedown",{
	bind:function(el,binding){
		new vueTouch(el,binding,"swipedown");
	}
});
Vue.directive("swipeup",{
	bind:function(el,binding){
		new vueTouch(el,binding,"swipeup");
	}
});
Vue.directive("longtap",{
	bind:function(el,binding){
		new vueTouch(el,binding,"longtap");
	}
});

2018-03-08
有朋友提出一个bug
“v-for循环 生命周期后 获取不到新值 比如更新了数据”

这个问题是v-for的就地复用机制导致的,也就是可以复用的dom没有重复渲染,官方给出的方法是需要为每项提供一个唯一 key 属性。理想的 key 值是每项都有的且唯一的 id。

我的解决方案是directive的钩子函数参数有一个vnode,这个是虚拟dom节点,给vnode.key赋予一个随机id,强制dom刷新。

Vue.directive("tap",{
	bind:function(el,binding,vnode){
		vnode.key = randomString()//randomString会返回一个随机字符串
		new vueTouch(el,binding,"tap");
	}
});

最新的版本已经在GitHub更新
https://github.com/904790204/vue-touch

最近一直在忙,最新的用法已经更新,可以直接从npm下载安装kim-vue-touch,传参方式也做了修改,有什么问题可以直接联系我,qq:904790204

你可能感兴趣的:(vue,vue,touch,vue-touch,tap,directive)