Vue custom command implementation v-tap plug-in vue-touch is based on hammer, which is too huge for pages with simple gestures!
So I want to implement the most common gesture tap by myself. Following the User-Defined commands and plug-in documents, a v-tap command was executed last night, throwing out this dry item.
Instructions and plug-ins
The user-defined commands and plug-ins are also described in simple and detailed documents.
I will start with this plug-in and use three APIs. If you are not familiar with it, you 'd better read the documentation first to avoid the obfuscation of the code below.
Instructions
1. update (nVal, oVal)
2. acceptStatement
Plug-ins
Vue. use ()
Then we need to learn the format of Vue plug-in like writing jQuery plug-ins.
Continue official documentation
MyPlugin. install = function (Vue, options) {// 1. add a global method or attribute Vue. myGlobalMethod =... // 2. add global resource Vue. directive ('My-ctive Ve', {}) // 3. add an instance Vue. prototype. $ myMethod = ...}
Are you still not quite clear about it? Then we can directly look at the author's plug-in code.
;(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) } })()
I deleted all unnecessary irrelevant code and found that the actual format is like this. The rest is to use our own js skills to directly write it.
PS: I have not found any information about the isFn: true attribute in this document. I personally think it may be a comment, this command requires the fn expression (this is the expression of the command. For details, refer to the Command instance attribute ).
Just do it
First, write the outer layer according to the plug-in format.
;(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); } })();
Then write our own custom commands in our vueTap. install.
Vue. directive ('tap', {isFn: true, bind: function () {}, update: function (fn) {}, unbind: function () {}, isTap: function () {// determine whether it is a tap}, touchstart: function (e, self) {}, touchend: function (e, self ){}});};
Since only update can have parameters that can be passed, we can receive the expression, so I wrote the event binding process in update.
PS: Of course, some friends like to assign fn to this (this here is the directve instance), and finally bind events to bind events. I have not found any standards, and I still don't know what to write.
Update: function (fn) {var self = this; // save this for future use // attributes and Methods bound to ve ctive // you can use self. xxx self. touchstart () gets self. tapObj = {}; // initialize our tap object if (typeof fn! = 'Function') {// do not do anything for me! Return console. error ('the param of ctictive "v-tap" must be a function! ');} Self. handler = function (e) {// save a handler for the current directive and call e. tapObj = self. tapObj; // assign the value of our tap object to the native event object to facilitate obtaining the fn parameter in the callback. call (self, e) ;}; // extract the start and end values and write them on direve VE. // because only the tap event exists, therefore, we do not need to process this in the move process. el. addEventListener ('touchstart', function (e) {self. touchstart (e, self) ;}, false); this. el. addEventListener ('touchend', function (e) {self. touchend (e, self, fn) ;}, false );}
The update process is simple. It involves initialization, event binding, and instance assignment.
The last step is the logic processing of isTap, touchstart, and 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);}
Finally, there is a big problem. How can we make our expression acceptable for passing parameters?
Add an acceptStatement: true to our ve (for details, see acceptStatement)
Summary
I wrote this v-tap plug-in to share my experiences with you.
1. In update, this indicates a directive instance, not a vm or dom.
2. You can customize attributes and methods in the directive ('name', {}) object. The call is self. xxx.
3. Enable custom commands to accept the inline statement acceptStatement: true
4. Do not forget Vue. use (obj) for the last interface)
I am not here to v-tap.stop, v-tap.prevent, v-tap.stop.prevent to do processing, you can achieve it by yourself! It is also very simple.