10个Vue项目必备的高频实用自定义指令(复制即用)

 更新时间:2026年04月10日 08:30:22   作者:前端Hardy  
在实际开发中,很多重复逻辑用自定义指令来做最优雅,既不污染组件,复用性又极强, 所以本文小编为大家整理了 10 个企业级最常用的 Vue 自定义指令,复制到项目就能直接用,建议收藏进你的工具库

在实际开发中,很多重复逻辑(权限控制、防抖点击、图片懒加载、文本复制等)用自定义指令来做最优雅,不污染组件、不写冗余代码、复用性极强。

今天整理了 10 个企业级最常用的 Vue 自定义指令,Vue2 / Vue3 都能跑,复制到项目里直接用,建议收藏进你的工具库。

1. v-permission 按钮权限控制(后台系统必用)

根据权限码控制按钮显隐,后端返回权限列表直接用。

// directives/permission.js
import { useUserStore } from '@/stores/user'

export default {
  mounted(el, binding) {
    const { permissions } = useUserStore()
    const value = binding.value
    if (!value) return
    // 无权限则移除元素
    if (!permissions.includes(value)) {
      el.parentNode?.removeChild(el)
    }
  }
}

使用:

<button v-permission="'user:add'">添加用户</button>

2. v-debounce 防抖点击(搜索/提交防重复)

// directives/debounce.js
export default {
  mounted(el, binding) {
    const { func, delay = 300 } = binding.value
    let timer = null
    el.addEventListener('click', () => {
      clearTimeout(timer)
      timer = setTimeout(() => func(), delay)
    })
  }
}

使用:

<button v-debounce="{ func: handleSearch, delay: 500 }">搜索</button>

3. v-throttle 节流指令(滚动/防狂点)

// directives/throttle.js
export default {
  mounted(el, binding) {
    const { func, delay = 500 } = binding.value
    let lastTime = 0
    el.addEventListener('click', () => {
      const now = Date.now()
      if (now - lastTime >= delay) {
        func()
        lastTime = now
      }
    })
  }
}

4. v-copy 一键复制文本

// directives/copy.js
export default {
  mounted(el, binding) {
    el.addEventListener('click', () => {
      const text = binding.value
      navigator.clipboard.writeText(text).then(() => {
        ElMessage.success('复制成功')
      })
    })
  }
}

使用:

<span v-copy="orderNo">复制订单号</span>

5. v-longpress 长按指令

// directives/longpress.js
export default {
  mounted(el, binding) {
    const { func, time = 1000 } = binding.value
    let timer = null
    el.addEventListener('mousedown', () => {
      timer = setTimeout(() => func(), time)
    })
    el.addEventListener('mouseup mouseleave', () => clearTimeout(timer))
  }
}

6. v-input-number 仅允许输入数字(支持小数)

// directives/number.js
export default {
  mounted(el) {
    const input = el.tagName === 'INPUT' ? el : el.querySelector('input')
    input.addEventListener('input', () => {
      input.value = input.value.replace(/[^\d.]/g, '')
      const arr = input.value.split('.')
      if (arr.length > 2) input.value = arr[0] + '.' + arr[1]
    })
  }
}

使用:

<el-input v-input-number v-model="num" />

7. v-lazy 图片懒加载(性能优化)

// directives/lazy.js
export default {
  mounted(el, binding) {
    const observer = new IntersectionObserver(([{ isIntersecting }]) => {
      if (isIntersecting) {
        el.src = binding.value
        observer.unobserve(el)
      }
    })
    observer.observe(el)
  }
}

使用:

<img v-lazy="imgUrl" alt="" />

8. v-draggable 元素拖拽

// directives/drag.js
export default {
  mounted(el) {
    el.style.cssText += ';position:fixed;cursor:move;'
    el.addEventListener('mousedown', (e) => {
      const x = e.clientX - el.offsetLeft
      const y = e.clientY - el.offsetTop
      const move = (e) => {
        el.style.left = e.clientX - x + 'px'
        el.style.top = e.clientY - y + 'px'
      }
      document.addEventListener('mousemove', move)
      document.addEventListener('mouseup', () => {
        document.removeEventListener('mousemove', move)
      }, { once: true })
    })
  }
}

9. v-watermark 页面水印(防截图)

// directives/watermark.js
export default {
  mounted(el, binding) {
    const text = binding.value || '内部资料'
    const canvas = document.createElement('canvas')
    canvas.width = 200
    canvas.height = 150
    const ctx = canvas.getContext('2d')
    ctx.font = '14px Arial'
    ctx.fillStyle = 'rgba(0,0,0,0.1)'
    ctx.rotate(-0.2)
    ctx.fillText(text, 20, 50)
    el.style.background = `url(${canvas.toDataURL()}) repeat`
  }
}

10. v-auto-height 自适应高度(表格/弹窗常用)

自动计算高度,避免滚动条错乱

// directives/autoHeight.js
export default {
  mounted(el) {
    const resize = () => {
      const top = el.getBoundingClientRect().top
      el.style.height = window.innerHeight - top - 20 + 'px'
    }
    resize()
    window.addEventListener('resize', resize)
    el._resize = resize
  },
  unmounted(el) {
    window.removeEventListener('resize', el._resize)
  }
}

统一注册(Vue3)

directives/index.js 统一导出:

import permission from './permission'
import debounce from './debounce'
// ...其他

export default {
  install(app) {
    app.directive('permission', permission)
    app.directive('debounce', debounce)
  }
}

main.js 引入:

import directives from '@/directives'
app.use(directives)

到此这篇关于10个Vue项目必备的高频实用自定义指令(复制即用)的文章就介绍到这了,更多相关Vue自定义指令内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 解决vue刷新页面以后丢失store的数据问题

    解决vue刷新页面以后丢失store的数据问题

    这篇文章主要介绍了解决vue刷新页面以后丢失store的数据问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-08-08
  • ElementUI中利用table表格自定义表头Tooltip文字提示

    ElementUI中利用table表格自定义表头Tooltip文字提示

    这篇文章主要介绍了ElementUI中利用table表格自定义表头Tooltip文字提示,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-07-07
  • 查看当前vue项目所需Node.js版本的方法

    查看当前vue项目所需Node.js版本的方法

    这篇文章主要大家介绍了查看当前vue项目所需Node.js版本的方法,文章通过代码示例给大家介绍的非常详细,对大家的学习或工作有一定的帮助,需要的朋友可以参考下
    2023-11-11
  • Vue中this.$router和this.$route的区别及push()方法

    Vue中this.$router和this.$route的区别及push()方法

    这篇文章主要给大家介绍了关于Vue中this.$router和this.$route的区别及push()方法的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-05-05
  • 基于Vue3自定义实现图片翻转预览功能

    基于Vue3自定义实现图片翻转预览功能

    这篇文章主要为大家详细介绍了如何基于Vue3自定义实现简单的图片翻转预览功能,文中的示例代码讲解详细,具有一定的学习价值,有需要的小伙伴可以参考一下
    2023-10-10
  • VUE项目去除input 框值所有空格的操作方法

    VUE项目去除input 框值所有空格的操作方法

    这篇文章主要介绍了VUE项目去除input 框值所有空格的操作方法,主要包括去除空格的方法、正则和element ui写法,本文给大家讲解的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-10-10
  • vue如何设置描点跳转到对应页面

    vue如何设置描点跳转到对应页面

    这篇文章主要介绍了vue如何设置描点跳转到对应页面问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-05-05
  • 基于Vue3和SpringBoot实现Web实时消息推送功能

    基于Vue3和SpringBoot实现Web实时消息推送功能

    这篇文章主要介绍了WebSocket实现实时通信,对比HTTP低效,通过SpringBoot+Vue整合实现消息推送,涵盖聊天、股票等场景,文中有详细的代码示例供大家参考,需要的朋友可以参考下
    2025-05-05
  • Vue实现tab导航栏并支持左右滑动功能

    Vue实现tab导航栏并支持左右滑动功能

    本文给大家介绍利用Vue实现tab导航栏,并且通过flex布局实现左右滑动效果,通过代码给大家分享tab导航栏布局的实现,本文给大家展示了完整代码,需要的朋友参考下吧
    2021-06-06
  • Vue.directive()的用法和实例详解

    Vue.directive()的用法和实例详解

    这篇文章主要介绍了Vue.directive()的用法和实例 ,需要的朋友可以参考下
    2018-03-03

最新评论