vue3常用自定义指令封装v-permission,按钮权限控制,添加防抖节流

前言:

后台管理项目免不了要做权限控制,常见的分为路由级别和按钮级别,在此主要针对于按钮权限,比如说某个用户或者角色对数据有没有增删改查的权限,例如以下功能,巡查人员可以点击导入和新建,而一般用户只能选择下载模板。

一、创建

1.创建文件夹

项目是vue3版本,在项目的src文件夹下的shared文件下新建一个名为directives的文件夹,内置一个modules文件夹和index.ts文件,前者用于存放各个自定义指令业务逻辑便于区分和维护,后者用于集中整理注册所有的自定义指令。

2.创建自定义指令

在 directives文件夹下分别创建permission、debounce、throttle三个ts文件,分别用于存放权限控制,防抖和节流的业务逻辑,结构清晰,方便维护以及更低的耦合度。

①按钮权限:

实现逻辑是登陆后获取用户的按钮权限整理成一个数组buttonList存入store中,指令绑定按钮后传入binding参数,与buttonList中数据进行映射匹配,若找到则返回true,设置绑定元素显示,反之绑定元素设置隐藏。

import type { Directive, DirectiveBinding } from 'vue'
import { useRoutesStore } from '@/store/modules/routes'
import { BUTTON_PERMISSION_MAP } from '@/constants/button-permission'

const permission: Directive = {
  mounted(el: HTMLElement, binding: DirectiveBinding): void {
    const { value } = binding

    if (!value)
      return
    const curValue = BUTTON_PERMISSION_MAP[binding.value]
    const allBtnMap = useRoutesStore().buttonList
    // 可根据自己的业务修改此处实现逻辑
    if (!allBtnMap.includes(curValue))
      el.style.display = 'none'
    else
      el.style.display = 'auto'
  },
}

export default permission
②防抖函数

函数防抖是常见的项目交互优化方式,就是指触发事件后,在 n 秒内函数只能执行一次,如果触发事件后在 n 秒内又触发了事件,则会重新计算函数延执行时间。此功能用法一致,也可根据自己需求稍作修改。

import type { Directive, DirectiveBinding } from 'vue'
interface ElType extends HTMLElement {
  __handleClick__: () => any
}
const debounce: Directive = {
  mounted(el: ElType, binding: DirectiveBinding) {
    if (typeof binding.value !== 'function')
      return

    let timer: NodeJS.Timeout | null = null
    el.__handleClick__ = function () {
      if (timer)
        clearInterval(timer)

      timer = setTimeout(() => {
        binding.value()
      }, 500)
    }
    el.addEventListener('click', el.__handleClick__)
  },
  beforeUnmount(el: ElType) {
    el.removeEventListener('click', el.__handleClick__)
  },
}
export default debounce
③节流函数 

与上面防抖函数一样,节流也是常见的项目交互优化方式,主要是指在事件被触发后,在规定时间内无论再怎么触发只会调用一次函数,直到时间结束。节流函数根据业务需求传入等待时间,不传默认设置2s。

import type { Directive, DirectiveBinding } from 'vue'
interface ElType extends HTMLElement {
  __handleClick__: (event: MouseEvent) => any
  disabled: boolean
}
const throttle: Directive = {
  mounted(el: ElType, binding: DirectiveBinding) {
    if (typeof binding.value !== 'function')
      return
    const duration = binding.arg ? parseInt(binding.arg) : 2000
    let timer: NodeJS.Timeout | null = null
    el.__handleClick__ = function (event: MouseEvent) {
      if (timer)
        clearTimeout(timer)
      if (!el.disabled) {
        el.disabled = true
        el.classList.add('n-button--disabled')
        binding.value(event)
        timer = setTimeout(() => {
          el.disabled = false
          el.classList.remove('n-button--disabled')
        }, duration)
      }
    }
    el.addEventListener('click', el.__handleClick__)
  },
  beforeUnmount(el: ElType) {
    el.removeEventListener('click', el.__handleClick__)
  },
}
export default throttle
3.注册自定义指令

在index.ts文件中分别导入每个自定义指令对象,再遍历注册每一个指令。

import type { App } from 'vue'
import debounce from './modules/debounce'
import throttle from './modules/throttle'
import permission from './modules/permission'

const directivesList: any = {
  debounce,
  throttle,
  permission,
}

const setDirectives = {
  install(app: App<Element>) {
    Object.keys(directivesList).forEach((key) => {
      app.directive(key, directivesList[key])
    })
  },
}

export default setDirectives
4.挂载自定义指令

在根目录main.ts文件中导入index.ts中创建的指令setDirectives,在vue实例app上进行挂载,可在项目中任意位置提供全局使用。

二、使用 

类似于vue的v-if,v-for等内置指令,在页面功能按钮上,直接通过v-前缀加上自定义指令名称,即可使用封装的自定义指令。

1.权限指令使用

2.防抖指令使用

3.节流指令使用

  • 8
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值