# 定义多个全局指令

在src下创建directives文件,在modules创建多个指令文件,名称既是指令的名称,在index.js中会自动获取文件名来注册到Vue中。

├── directives
│   ├── index.js               # 入口文件
│   ├── modules                # 指令文件
│   │   ├── focus.js           # v-focus
│   │   └── click-out.js       # v-click-out

index.js文件

/**
 * @description 定义多个全局自定义指令
 * @author changz
 * @example 直接在main.js引入后就可以自动注册modules下的所有指令
 * */

import Vue from 'vue'

const files = require.context('./modules', false, /.+\.js$/)

// 按模块引入
// files.keys(): 打印出来为['./focus.js','/loadmore.js']
files.keys().forEach(fileName => {
  const directiveConfig = files(fileName) // 获取指令函数
  const directiveName = fileName // 获取指令名
    .replace(/^\.\//, '') // 去除开头的'./'
    .replace(/\.\w+$/, '') // 去除文件扩展名

  Vue.directive(directiveName, directiveConfig.default || directiveConfig)
})
/**
 * 自动获取焦点指令
 * @description input表单进入页面自动获取焦点
 * @author changz
 * @example
 * <a-input v-focus></a-button>
 * */
export default {
  inserted: function (el, binding, vnode) {
    el.focus()
  }
}
/**
 * 点击元素外触事件发指令
 * @description 如点击空白处关闭当前元素
 * @author changz
 * @example
 * <a-button v-click-out="triggerEvent">添加</a-button>
 * <a-button v-click-out="() => triggerEvent(index)">传参</a-button>
 * */

export default {
  // 初始化指令
  bind(el, binding) {
    function documentHandler(e) {
      // 这里判断点击的元素是否是本身,是本身,则返回
      if (el.contains(e.target)) {
        return false
      }
      // 判断指令中是否绑定了函数
      if (binding.expression) {
        // 如果绑定了函数 则调用那个函数,此处binding.value就是handleClose方法
        binding.value(e)
      }
    }
    // 给当前元素绑定个私有变量,方便在unbind中可以解除事件监听
    el.clickOutHide = documentHandler
    document.addEventListener('click', documentHandler)
  },
  unbind(el) {
    // 解除事件监听
    document.removeEventListener('click', el.clickOutHide)
    delete el.clickOutHide
  }
}

main.js引入全局使用

// mian.js

// 自定义指令
import '@/directives'