每个人都能实现的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 debounce(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() {
        debounce(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 来下载我们自己封装好的插件啦!.
原文地址:https://segmentfault.com/a/1190000012566413
每个人都能实现的vue自定义指令的更多相关文章
- vue自定义指令
		
Vue自定义指令: Vue.directive('myDr', function (el, binding) { el.onclick =function(){ binding.value(); } ...
 - vue自定义指令(Directive中的clickoutside.js)的理解
		
阅读目录 vue自定义指令clickoutside.js的理解 回到顶部 vue自定义指令clickoutside.js的理解 vue自定义指令请看如下博客: vue自定义指令 一般在需要 DOM 操 ...
 - vue自定义指令clickoutside使用以及扩展用法
		
vue自定义指令clickoutside使用以及扩展用法 产品使用vue+element作为前端框架.在功能开发过程中,难免遇到使用element的组件没办法满足特殊的业务需要,需要对其进行定制,例如 ...
 - vue自定义指令clickoutside扩展--多个元素的并集作为inside
		
都是个人理解,如果发现错误,恳请大家批评指正,谢谢.还有我说的会比较啰嗦,因为是以自身菜鸡水平的视角来记录学习理解的过程,见谅. 1.前言 产品使用vue+element作为前端框架.在功能开发过程中 ...
 - vue自定义指令,比onerror更优雅的方式实现当图片加载失败时使用默认图,提供三种方法
		
首先,来看下效果图(演示一下图片正常加载与加载失败时的效果) 在线体验地址:https://hxkj.vip/demo/vueImgOnerror/ 一.常规方法解决 我们都知道,img标签支持one ...
 - Vue自定义指令使用场景
		
当你第一次接触vue的时候,一定会使用到其中的几个指令,比如:v-if.v-for.v-bind...这些都是vue为我们写好的,用起来相当的爽.如果有些场景不满足,需要我们自己去自定义,那要怎么办呢 ...
 - Vue自定义指令使用方法详解 和 使用场景
		
Vue自定义指令的使用,具体内容如下 1.自定义指令的语法 Vue自定义指令语法如下: Vue.directive(id, definition) 传入的两个参数,id是指指令ID,definitio ...
 - 使用Vue自定义指令实现Select组件
		
完成的效果图如下: 一.首先,我们简单布局一下: <template> <div class="select"> <div class="i ...
 - vue 自定义指令的魅力
		
[第1103期]vue 自定义指令的魅力 点点 前端早读课 2017-11-08 前言 很多事情不能做过多的计划,因为计划赶不上变化.今日早读文章由富途@点点翻译分享. 正文从这开始- 在你初次接触一 ...
 
随机推荐
- zabbix部署监控端(server)以及页面优化
			
实验环境准备 172.20.10.2 server.zabbix.com 172.20.10.3 agent.zabbix.com 172.20.10.8 windows10 Server 端 [ro ...
 - Parameter ‘brOrderNo’ not found
			
org.apache.ibatis.binding.BindingException: Parameter 'brOrderNo' not found. Available parameters ar ...
 - 使用jq把js代码封装一个自己的插件
			
为什么要把js功能封装成插件呢?我觉得有以下几点吧 1.最基本的原因就是便于代码复用. 2.便于维护和管理. 3.提升自身的能力. 4.避免各个相同功能组件的干扰,以及一些作用域会相互影响的问题. j ...
 - 算法23-------岛屿的最大面积 LeetCode 695
			
一.题目: 给定一个包含了一些 0 和 1的非空二维数组 grid , 一个 岛屿 是由四个方向 (水平或垂直) 的 1 (代表土地) 构成的组合.你可以假设二维矩阵的四个边缘都被水包围着. 找到给定 ...
 - 电子邮件的三个协议: SMTP、IMAP、POP3
			
个人总结: 读完这篇文章需要10分钟 讲解了跟电子邮件有关的三个协议: SMTP(simple message transfer protocol 简单信息传输协议 IMAP (internet me ...
 - js本地对象——Date()
			
Date()是JavaScript的本地对象,用于获取当前的时间,包括年.月.日.时.分.秒,可以精确到毫秒级:该对象返回的是UTC 协调世界时(Coordinated Universal Time) ...
 - js判断 nan  null  undefined的方法
			
收集资料如下判断: 1.判断undefined: 复制代码代码如下: <span style="font-size: small;">var tmp = undefin ...
 - 【codeforces 235B】Let's Play Osu!
			
[题目链接]:http://codeforces.com/problemset/problem/235/B [题意] 让你玩一个游戏,游戏结果由一个长度为n的01字符组成; 这个结果的分数与连续的1的 ...
 - spring boot和maven的约定大于配置体现在哪些方面
			
spring boot和maven的约定大于配置体现在哪些方面? 两者都遵从了约定大于配置的路线 约定优于配置体现点: 1.maven的目录文件结构 1)默认有resources文件夹,存放资源配置文 ...
 - Knockout源代码精析-怎样解析demo元素,获取到bindings(二)?
			
接上文这里開始分析applyBindingsToNodeInternal.applyBindingsToNodeInternal方法例如以下: function applyBindingsToNode ...