vue-touch はハンマーに基づいていますが、通常の単純なジェスチャ ページには大きすぎます。
そこで、最もよく使用されるジェスチャータップの 1 つを自分で実装したいと思いました。カスタム命令とプラグインのドキュメントに従って、昨夜 v-tap 命令を実装し、この記事を投稿しました。
命令とプラグインの紹介
カスタム命令やプラグインについても公式ドキュメントで比較的簡単かつ詳細に紹介されているので、あまり詳しく説明しません。
まず最初に言っておきますが、このプラグインは 3 つの 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 スキルを使用して直接記述することができます。
追記: 属性「isFn:true」に関しては、ドキュメント内で関連情報が見つかりませんでした。個人的には、この命令には fn の式が必要であることを示すコメントであると考えられます (これは命令の式です。を参照)。詳細については、命令インスタンス属性を参照してください)。
やってみよう
まず、プラグインの形式に従って外側のレイヤーを書きます。
;(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 のみに渡すパラメーターがあり、式を受け取ることができるので、イベントをバインドしました 処理手順はすべて更新。
追記: もちろん、すべての fn をこれに割り当て (ここではこれはディレクティブ インスタンスです)、最後にバインド位置でイベントをバインドすることを好む友人もいます。基準が見つからず、どれを書いたら良いのか分かりません。
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); }
更新では、初期化、イベントのバインド、インスタンスへの値の割り当てのプロセスは非常に単純です。
最後のステップは、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); }
最後に大きな質問があります。式でパラメーターを受け入れるにはどうすればよいでしょうか?
<ul> <li v-for="el in list" v-tap="args($index,el,$event)" > {{el.name}}---{{el.age}} </li> </ul>
次に、属性 acceptStatement:true をディレクティブに追加する必要があります (詳細については、ドキュメント acceptStatement を参照してください)
概要
この v-tap プラグインは、いくつかの経験を共有するために作成されました。
1. update では、vm や dom ではなく、ディレクティブ インスタンスを指します。
2. directive('name',{}) オブジェクトでは、カスタマイズ可能な属性とメソッドを使用できます。呼び出しは self.xxx です
3. インライン ステートメントを受け入れるためのカスタム命令を有効にします
4. 最後のインターフェイスには Vue.use(obj) を忘れないでください
v-tap.stop、v- はありません。ここのtap.prevent、v-tap.stop.preventは処理に使用されており、自分で実装できます。こちらも非常にシンプル。