Skip to content

自定义指令

自定义 debounce

js
import { debounce as _debounce } from 'lodash-es'
const DEFAULT_TIME = 3000

export const debounce = {
  bind(el, { arg, modifiers, value }, vnode) {
    const isComponent = !!vnode.child
    const duration = Number(Object.keys(modifiers)[0]) || DEFAULT_TIME

    if (isComponent) {
      vnode.child.$on(arg, _debounce(value, duration))
    } else {
      el.addEventListener(arg, _debounce(value, duration))
    }
  },
}
  • 使用
template
<button v-debounce:click.1000="onHandleXX">自定义指令防抖</button>

自定义 permission

js
import store from '@/store'

function checkPermission(el, binding) {
  const { value } = binding
  const roles = store.getters && store.getters.roles

  if (value && value instanceof Array) {
    if (value.length > 0) {
      const permissionRoles = value

      const hasPermission = roles.some((role) => {
        return permissionRoles.includes(role)
      })

      if (!hasPermission) {
        el.parentNode && el.parentNode.removeChild(el)
      }
    }
  } else {
    throw new Error(`need roles! Like v-permission="['admin','editor']"`)
  }
}

export default {
  inserted(el, binding) {
    checkPermission(el, binding)
  },
  update(el, binding) {
    checkPermission(el, binding)
  },
}
  • 使用
template
<button v-permission="['admin']"> 自定义指令permission </button>

自定义 clipboard

js
const Clipboard = require('clipboard')
if (!Clipboard) {
  throw new Error('you should npm install `clipboard` --save at first ')
}

export default {
  bind(el, binding) {
    if (binding.arg === 'success') {
      el._v_clipboard_success = binding.value
    } else if (binding.arg === 'error') {
      el._v_clipboard_error = binding.value
    } else {
      const clipboard = new Clipboard(el, {
        text() {
          return binding.value
        },
        action() {
          return binding.arg === 'cut' ? 'cut' : 'copy'
        },
      })
      clipboard.on('success', (e) => {
        const callback = el._v_clipboard_success
        callback && callback(e) // eslint-disable-line
      })
      clipboard.on('error', (e) => {
        const callback = el._v_clipboard_error
        callback && callback(e) // eslint-disable-line
      })
      el._v_clipboard = clipboard
    }
  },
  update(el, binding) {
    if (binding.arg === 'success') {
      el._v_clipboard_success = binding.value
    } else if (binding.arg === 'error') {
      el._v_clipboard_error = binding.value
    } else {
      el._v_clipboard.text = function () {
        return binding.value
      }
      el._v_clipboard.action = function () {
        return binding.arg === 'cut' ? 'cut' : 'copy'
      }
    }
  },
  unbind(el, binding) {
    if (binding.arg === 'success') {
      delete el._v_clipboard_success
    } else if (binding.arg === 'error') {
      delete el._v_clipboard_error
    } else {
      el._v_clipboard.destroy()
      delete el._v_clipboard
    }
  },
}
  • 使用
template
<button
    v-clipboard:copy="inputData"
    v-clipboard:success="clipboardSuccess"
> 自定义指令copy </button>