vue自定義指令實(shí)現(xiàn)v-tap插件
放棄jQuery,擁抱MVVM,擁抱組件吧!
vue-touch基于hammer,對于普通簡單手勢的頁面來說過于龐大!
于是想自己實(shí)現(xiàn)一個最常用的手勢tap。順著自定義指令和插件文檔,昨晚實(shí)現(xiàn)了一個v-tap指令,丟出這篇干貨。
指令與插件介紹
自定義指令和插件官方文檔中也介紹比較簡單詳細(xì),就不過多介紹。
我先說下本插件就用了三個API,如果大家不了解最好先事先看下文檔避免后面的代碼看的迷糊。
指令部分
1.update(nVal,oVal)
2.acceptStatement
插件部分
Vue.use()
接著我們需要像寫jQuery插件一樣學(xué)習(xí)寫Vue插件的格式。
繼續(xù)官方文檔
MyPlugin.install = function (Vue, options) {
// 1. 添加全局方法或?qū)傩?
Vue.myGlobalMethod = ...
// 2. 添加全局資源
Vue.directive('my-directive', {})
// 3. 添加實(shí)例方法
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)
}
})()
我把多余無關(guān)代碼都刪除了,可以發(fā)現(xiàn)其實(shí)格式就是如此,剩下的就是利用我們自己js的功底直接編寫即可。
PS:關(guān)于 isFn:true 這個屬性,我在文檔中沒有查到相關(guān)信息,個人認(rèn)為可能是一種注釋,代表這個指令是需要fn的expression(這個是指令的表達(dá)式,詳見指令實(shí)例屬性)。
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才有參數(shù)可傳,可以接收到我們expression,于是我把事件綁定處理過程都寫在了update里。
PS: 當(dāng)然也有小伙伴喜歡在這把fn都賦予在this(這里的this是directve實(shí)例)上,最后在bind的地方綁定事件。這個我并沒有找到規(guī)范,還不知道寫哪比較好。
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) { //給當(dāng)前directive存?zhèn)€handler方便之后調(diào)用
e.tapObj = self.tapObj;
//把我們的tap對象賦值給原生event對象上,方便回調(diào)里獲取參數(shù)
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很簡單,就是一些初始化,事件綁定和給實(shí)例賦值的過程。
最后就是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)
總結(jié)
寫了這個v-tap插件幾個心得分享給大家。
1.在update里的this指向是directive實(shí)例,而不是vm,也不是dom
2.在directive('name',{}) 對象里可自定義屬性和方法。調(diào)用就是self.xxx
3.開啟自定義指令接受內(nèi)聯(lián)語句 acceptStatement:true
4.最后的接口別忘了 Vue.use(obj)
我這里沒有對v-tap.stop, v-tap.prevent,v-tap.stop.prevent做處理,大家可以自己實(shí)現(xiàn)!也灰常簡單。
(我之后會對v-tap進(jìn)行補(bǔ)充)
最后丟出github地址: https://github.com/MeCKodo/vue-tap
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
vue單頁應(yīng)用加百度統(tǒng)計(jì)代碼(親測有效)
這篇文章主要介紹了vue單頁應(yīng)用加百度統(tǒng)計(jì)代碼的解決方法,需要的朋友參考下吧2018-01-01
vue 和vue-touch 實(shí)現(xiàn)移動端左右導(dǎo)航效果(仿京東移動站導(dǎo)航)
這篇文章主要介紹了vue 和vue-touch 實(shí)現(xiàn)移動端左右導(dǎo)航效果(仿京東移動站導(dǎo)航),需要的朋友可以參考下2017-04-04
vue 項(xiàng)目中使用websocket的正確姿勢
這篇文章主要介紹了vue 項(xiàng)目中使用websocket的實(shí)例代碼,通過實(shí)例代碼給大家介紹了在utils下新建websocket.js文件的方法,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-01-01
vue 登錄滑動驗(yàn)證實(shí)現(xiàn)代碼
這篇文章主要介紹了vue 登錄滑動驗(yàn)證實(shí)現(xiàn)代碼,代碼簡單易懂,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下2018-08-08

