每个人都能实现的vue自定义指令

前文

  先来bb一堆废话哈哈..
  
  用vue做项目也有一年多了.除了用别人的插件之外.自己也没尝试去封装指令插件之类的东西来用.
  
  刚好最近在项目中遇到一个问题.(快速点击按钮多次触发多次绑定的方法),于是就想说自己封装一个 
  自定义指令来解决这个问题,于是便有了自己的第一个vue自定义指令 vue-reclick . 
 

vue-reclick 传送门

哈哈,好了!广告打完了,开始进入正题(等一下,听说star有奖哦)...

1.使用场景

 在vue 2.0中,有的情况下,你需要对普通DOM元素进行底层操作,这时候就需要用到自定义指令!   

2.api详解

 其实关于vue自定义指令的使用 vue官方文档已经说的非常清楚.这里只是简单的照搬,哦不,讲一下 (23333..)..
 1.首先创建一个指令自定义对象directObj。
 
 let directObj = {}.
 
 2.vue为所有指令的钩子函数都提供一些函数参数。
    
 let args = {
  el:'指令所绑定的元素,可以用来直接操作 DOM ',
  binding:{
   name:'指令名,不包括 v- 前缀。',
   value:'指令的绑定值,例如:v-my-directive="1 + 1" 中,绑定值为 2。',
   oldValue:'指令绑定的前一个值,仅在 update 和 componentUpdated 钩子中可用。无论值是否改变都可用。',
   expression:"字符串形式的指令表达式。例如 v-my-directive="1 + 1" 中,表达式为 "1 + 1"",
   arg:"传给指令的参数,可选。例如 v-my-directive:foo 中,参数为 "foo"",
   modifiers:"一个包含修饰符的对象。例如:v-my-directive.foo.bar 中,修饰符对象为 { foo: true, bar: true }。",
   vnode:"Vue 编译生成的虚拟节点。",
   oldVnode:"上一个虚拟节点"
  }
 }
 
 3.在directObj上可根据需要定义一些钩子函数
 
 directObj.bind = function({...args }){
 
     //只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。
 } 
 
 directObj.inserted= function({...args }){
 
     //被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。
 } 

 directObj.update= function({...args }){
 
     //所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。
     指令的值可能发生了改变,也可能没有。 
     但是你可以通过比较更新前后的值来忽略不必要的模板更新 
 }

 directObj.componentUpdated= function({...args }){
 
     //指令所在组件的 VNode 及其子 VNode 全部更新后调用。
 }
 
 directObj.unbind= function({...args }){
 
     //只调用一次,指令与元素解绑时调用。
 }

 4.注册自定义指令
  (1).全局注册:
  
      Vue.directive('指令名称','指令对象');
      例:Vue.directive('reclick',directObj);
      注意:全局注册自定义指令需在实例化Vue之前.
    
  (2).局部(组件)注册:
  
      export default{ 
       directives:{
         '指令名称':'指令配置'
       }
      }
      
      例:
      
      export default{ 
       directives:{
         'reclick':directObj
       }
      }

3.封装自定义指令

 好了,简单的讲(抄)完 自定义指令相关的api,接下来我们通过vue-reclick来简单的讲解一下如何封装一个vue自定义指令吧.

 由于vue-reclick 只是用来解决一个问题的小东西,所以代码也相对简单,这里主要讲一个封装自定义指令的过程.
    
 下面我们先来看下vue-reclick的源码:
 ;(function() {
  /**
   * 函数节流
   *
   * @param {any} method 方法名
   */
  function throttle(method) {
    clearTimeout(method.tId);
    method.tId = setTimeout(function() {
      method.call();
    }, 200);
  }
  /**
   * 事件绑定
   *
   * @param {any} element  绑定dom
   * @param {any} event    事件类型
   * @param {any} listener 方法
   */
  function addEvent(element, event, listener) {
    if (element.addEventListener) {
      element.addEventListener(event, listener, false);
    } else if (element.attachEvent) {
      element.attachEvent('on' + event, listener);
    } else {
      element['on' + event] = listener;
    }
  }
  var vueReclick = {};
  var reclick = {
    bind: function(el, binding) {
      addEvent(el, 'click', function() {
        throttle(binding.value);
      });
    },
    unbind: function(el) {
      addEvent(el, 'click', function() {});
    }
  };

  vueReclick.install = function(Vue) {
    Vue.directive('reclick', reclick);
  };

  if (typeof exports == 'object') {
    module.exports = vueReclick;
  } else if (typeof define == 'function' && define.amd) {
    define([], function() {
      return vueReclick;
    });
  } else if (window.Vue) {
    window.vueReclick = vueReclick;
    Vue.use(vueReclick);
  }
})();
1.将所有代码包裹在一个立即执行函数之中.

  立即执行函数有自己的作用域,可以避免变量冲突与污染.    
  
  将独立的功能封装在自包含模块中.  

2.vue-reclick功能相关的代码这里简单说明下.

  这里封装了两个方法(1.throttle,2.addEvent)
    
  一个指令配置对象(reclick)

  在reclick对象里定义了bind方法,在指令绑定到dom的时候,在dom上绑定点击事件,并获取指令绑定的方法名称.
  在触发点击事件的时候通过函数节流的方法来调用该方法,从而解决短时间快速点击触发多次方法的问题.
    
  在reclick对象里定义了unbind方法,在指令与dom解绑的时候,将传入方法与dom进行解绑..

3.定义一个vueReclick插件对象,并在该对象上定义一个install方法.

(Vue.js 的插件应当有一个公开方法 install 。这个方法的第一个参数是 Vue 构造器)

4.在install方法里全局注册指令

 vueReclick.install = function(Vue) {
    Vue.directive('reclick', reclick);
 };
 
5.兼容多种模块规范暴露该插件

  if (typeof exports == 'object') {
    module.exports = vueReclick;
  } else if (typeof define == 'function' && define.amd) {
    define([], function() {
      return vueReclick;
    });
  } else if (window.Vue) {
    window.vueReclick = vueReclick;
    Vue.use(vueReclick);
  }

6.到这一步,其实一个简单的自定义组件就已经大功告成了.

7.最后.我们来讲一下如何在项目中引入vueReclick并使用.

  (1).非node环境中
      
    在第5点我们在else if(window.Vue)中其实已经Vue的全局方法来使用该插件.
    所以我们可以直接在项目中使用该指令.
    例:https://github.com/webfansplz/vue-reclick/blob/master/example/index.html

  (2).node环境中

    我们可以在项目入口文件中引入该插件,然后全局使用它,下面我们会讲解如何将插件发布到Npm.
    例:
    import vueReclick from 'vue-reclick';
    Vue.use(vueReclick);

4.将封装好的插件发布到npm.

1.在Npm官网注册一个账号

2.在项目目录下 使用npm login 登录. 

3.在项目目录下 使用npm publish 上传插件

4.大功告成,这样以后我们在所有项目中就都可以使用npm install 来下载我们自己封装好的插件啦!.
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,847评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,208评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,587评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,942评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,332评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,587评论 1 218
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,853评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,568评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,273评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,542评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,033评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,373评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,031评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,073评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,830评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,628评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,537评论 2 269

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 170,568评论 25 707
  • 前段时间看到一个消息,一位车主哭诉他刚买了的新车,去车管车上牌,在途中没有违章违规,可是却被交警给拦了下来,直接扣...
    走走看看121阅读 885评论 0 0
  • 一互惠,二承诺和一致,三,权威,四社会认同,五稀缺 三,权威,主要表现在头衔,二是衣着,
    笑颜于粤阅读 143评论 6 1
  • 一路走一路买,走到东街时手上已经拎不动了,回头再看看这条老横街,嗯!我喜欢的市井生活,大概就是这个味道吧。对了,还...
    河马家的书奴阅读 138评论 0 2
  • 翔翔最近越来越依恋爸爸了,呃,谁让他妈爱河东狮吼,每次都是茆同志出来哄,满足了翔翔要撒娇的需求,茆同志耐心越...
    爱自满溢阅读 103评论 0 0