代码改变世界

vue自定义指令(Directive中的clickoutside.js)的理解

2017-06-04 17:50 龙恩0707 阅读(...) 评论(...) 编辑 收藏

阅读目录

vue自定义指令clickoutside.js的理解

vue自定义指令请看如下博客:

vue自定义指令

一般在需要 DOM 操作时我们都需要使用自定义指令的方式去实现,当然一些特殊的事件监听也可以使用指令,例如监听外部点击事件:

我们可以看下 clickoutside.js 如何实现的,如下代码:

const clickoutsideContext = '@@clickoutsideContext';

export default {
  /*
   @param el 指令所绑定的元素
   @param binding {Object} 
   @param vnode vue编译生成的虚拟节点
   */
  bind (el, binding, vnode) {
    const documentHandler = function(e) {
      console.log(el)
      console.log(e.target);
      console.log(vnode);
      console.log(binding);
      
      if(!vnode.context || el.contains(e.target)) {
        return false;
      }
      if (binding.expression) {
        vnode.context[el[clickoutsideContext].methodName](e)
      } else {
        el[clickoutsideContext].bindingFn(e);
      }
    }
    el[clickoutsideContext] = {
      documentHandler,
      methodName: binding.expression,
      bindingFn: binding.value
    }
    setTimeout(() => {
      document.addEventListener('click', documentHandler);
    }, 0)
  },
  update (el, binding) {
    el[clickoutsideContext].methodName = binding.expression;
    el[clickoutsideContext].bindingFn = binding.value;
  },
  unbind(el) {
    document.removeEventListener('click', el[clickoutsideContext].documentHandler);
  }
}

在外部调用 clickoutside.vue 代码如下:

<template>
  <div v-clickoutside="handleClickOutSide">1111111</div>
</template>

<script>
  import clickoutside from '../../directive/clickoutside';
  export default {
    methods: {
      handleClickOutSide(e) {
        // 当外部被点击时调用
        console.log(e);
        console.log(111)
      }
    },
    directives: {
      clickoutside
    }
  }
</script>

具体效果可以 查看git上的demo

把代码克隆下来,在本地运行项目 npm run dev 就可以启动本地项目预览~ 

下面我们来分下下 如上打印的字段含义:

当我随便在document点击一下,会打印console.log() 如下信息的含义:

1. console.log(el);  指被绑定的元素,打印信息如下:

<div>1111111</div>;

2. console.log(e.target); 打印信息如下:

3. console.log(vnode); 打印信息如下:

4. console.log(binding); 打印信息如下:

当我点击一下,会调用外部的方法:

methods: {
      handleClickOutSide(e) {
        // 当外部被点击时调用
        console.log(e);
        console.log(111)
      }
 },