1.vue 指令
Vue 提供自定义实现指令的功能, 和组件类似, 可以是全局指令和局部指令, 详细可以参见 vue 官网自定义指令一节 ().
2.v-tap 指令实现
我个人的理解, 编写指令即是在 vue 指令对象提供的钩子函数中做相应的逻辑处理, tap 指令是在 bind 钩子函数中做相应的处理, 首先, 要明白的是 tap 是为了处理 click 事件在 iPhone 上的存在 300ms 的延时, 这样使得连续点击很不流畅, tap 通过移动端的 touchstart 事件和 touchend 事件判断移动距离为零的话, 则触发绑定的函数, 话不多说, 上代码:
- Vue.directive('tap',{
- bind(el, binding, vNode){
- let expression = binding.value;
- let handler = expression.name;
- let args = expression.args
- on(el, 'touchstart', (e)=>{
- let startX = e.changedTouches[0].clientX;
- let startY = e.changedTouches[0].clientY;
- once(el, 'touchend',(ev)=>{
- let disX = Math.abs(ev.changedTouches[0].clientX-startX);
- let disY = Math.abs(ev.changedTouches[0].clientY-startY);
- if(disX == 0 && disY ==0){
- handler(args);
- }
- })
- })
- }
- })
使用示例: <div v-tap="{ name : mymethod, args:{arg1:11, args2:22} }"></div>
3. 总结
当我们需要复用一些 dom 底层操作的时候, 可以考虑使用 vue directive 的方式复用代码.
下面看下 vue tap 事件的实现代码
前两天做了个 tap.JS 插件, 实现了移动端 touch 事件模拟 click 事件, 解决点击延迟的问题, 但是在 vue 中并不能用 v-tap 来调用, 所以今天做了 vue 版的 vue-tap.JS. 此前也曾用过其他的插件来实现 v-tap, 但方式仍有些累赘, 于是便用了更简洁的方式来实现, 下面附上代码 (只支持 vue2.0+).
- vue-tap.JS
- /*!
- * vue-tap.JS
- * by weijianhua https://GitHub.com/weijhfly/vue-tap
- */
- ;(function (factory) {
- if (typeof define === 'function' && define.amd) {
- define(function(){return factory;});
- }else if (typeof exports == "object") {
- module.exports = factory;
- }else{
- Vue.use(factory);
- }
- }({
- master:{
- bind: function (el, binding) {
- var isTouch = "ontouchend" in document;
- el.exec = function (e) {
- var data = binding.value;
- data[0].apply(this, data.slice(1));
- };
- if (isTouch) {
- //touchstart
- el.addEventListener('touchstart', function (e) {
- binding.modifiers.stop && (e.stopPropagation());
- var t = e.touches[0];
- el.startX = t.clientX;
- el.startY = t.clientY;
- el.sTime = + new Date;
- });
- //touchend
- el.addEventListener('touchend', function (e) {
- binding.modifiers.stop && (e.stopPropagation());
- var t = e.changedTouches[0];
- el.endX = t.clientX;
- el.endY = t.clientY;
- if((+ new Date)-el.sTime<300){
- if(Math.abs(el.endX-el.startX)+Math.abs(el.endY-el.startY)<20){
- e.preventDefault();
- el.exec();
- }
- }
- });
- }else {
- //click
- el.addEventListener('click', function (e) {
- binding.modifiers.stop && (e.stopPropagation());
- el.exec();
- });
- }
- },
- componentUpdated : function(el,binding) {
- el.exec = function () {
- var data = binding.value;
- data[0].apply(this, data.slice(1));
- };
- },
- unbind: function (el) {
- el.exec = null;
- }
- },
- install:function(){
- Vue.directive('tap', this.master);
- }
- }))
demo.html
- <!DOCTYPE HTML>
- <HTML lang="en">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1,maximum-scale=1.0, user-scalable=0" />
- <title>vue plugin test</title>
- <style type="text/CSS">
- strong{
- font-size: 15px;
- }
- pre{
- padding: 16px 0;
- overflow: auto;
- line-height: 1.45;
- background-color: #f6f8fa;
- border-radius: 3px;
- }
- </style>
- </head>
- <body style="padding:30px;">
- <div id="App">
- <pre>
- <strong>vue-tap.JS</strong>
- <b > 简洁的调用方式:</b>
- v-tap="[方法, 参数一, 参数二...]"
- <b > 获取参数:</b>
- methods:{
- tap:function(参数一, 参数二...){
- console.log(参数一, 参数二...);
- }
- }
- <b > 阻止冒泡:</b>
- v-tap.stop
- </pre>
- <hr>
- <div v-for="(l,i) in list">
- <div v-tap="[tap,l,i]">li-{{l}}-{{i}}</div>
- </div>
- <br>
- <hr>
- <div v-tap="[test,'parent']">
- parent<br><br>
- <button v-tap.stop="[test,'son']">stop propagation</button>
- </div>
- </div>
- <script src="https://cdn.bootcss.com/vue/2.5.13/vue.js"></script>
- <script src="vue-tap.JS"></script>
- <script>
- new Vue({
- el:'#App',
- data:{
- list:['a','b','c','e','f']
- },
- methods:{
- tap:function(i,k){
- console.log(i,k);
- },
- test:function(i){
- console.log(i);
- }
- }
- })
- if(Windows.innerWidth <768){
- document.getElementsByTagName('body')[0].style.padding = 0;
- }
- </script>
- </body>
- </HTML>
- GitHub: https://GitHub.com/weijhfly/vue-tap
参考了其他 vue-tap 插件, 但仍有需要完善的地方, 后续更新. 此外, 在移动端解决点击延迟问题, 还是比较推荐 fastclick, 兼容性较好且方便使用, 不过相对而言模拟 tap 事件体积较小, 也可以拿来练手了.
总结
以上所述是小编给大家介绍的 vue 自定义 tap 指令及 tap 事件的实现, 希望对大家有所帮助, 如果大家有任何疑问请给我留言, 小编会及时回复大家的. 在此也非常感谢大家对脚本之家网站的支持!
来源: http://www.jb51.net/article/147634.htm