vue自定义指令(v-auth等)

防止按钮多次点击,重复请求

export default () => {

  Vue.directive('preventReClick', {
    inserted: (el, binding, vNode) => {
      console.log('el:', el)
      console.log('el:', el.disabled)
      // el.disabled = true // Mock
      el.addEventListener('click', () => {
        console.log('指令click', el.disabled)
        if (!el.disabled) {
          el.disabled = true
          setTimeout(() => {
            el.disabled = false
          }, binding.value || 300)
        }
      })
    }
  })
}

权限按钮

import Vue from 'vue'
/*或者直接使用项目组提供的包,直接使用他的v-auth*/
export default () => {
  Vue.directive('auth', {
    inserted: (el, binding, vNode) => {
      let authList = ['200', '201']
      // console.log('auth指令:',el,binding)
      // console.log('auth指令vNode:',vNode)
      // console.log('auth指令vNode:',vNode.context.$store.state)
      authList = vNode.context.$store.state.deviceMgmt.accessList || []
      if (authList.includes(binding.value)) {

      } else {
        el.parentNode.removeChild(el)
      }
    }
  })
}

权限的几种场景:

https://www.cnblogs.com/7c89/p/15761719.html

v-auth优化:增加some等场景

v-auth传入的权限码可以是String或者Array,此外还提供跟数组some和every方法一样的修饰符。

/**
 * auth指令 v-auth="Array or String"
 * 传入的权限码可以是数组或者是字符串
 * 此外还有两个修饰符 some 和 every
 * v-auth.some="Array" 表示满足其中一个资源即可(不设置修饰符情况下默认为some)
 * v-auth.every= "Array" 表示列表的所资源必须存在
 * 调用实例:
 *  <span v-auth.some="['admin1', 'admin2']"></span>
 *  <span v-auth.every="['admin1', 'admin2']"></span>
 *  <span v-auth="'admin1'"></span>
 */

// 删除节点dom
const remove = (el) => el.parentNode.removeChild(el)

Vue.directive('auth', {
  inserted: (el, binding, vNode) => {    
    const { $root: vm } = vNode.context
    // 获取当前用户拥有的权限列表(根据自身业务获取)
    const { access } = vm.$store.state.user
    // 获取传入的权限码value(string or array)和修饰符modifiers
    let { value, modifiers } = binding

    // 判断条件:当传入的值不是数组或者字符串时,直接隐藏元素
    if (
      !(
        typeof value === 'string' ||
        value instanceof Array
      ) ||
      !value
    ) {
      remove(el)
      return console.error('please set the value to a string or array.')
    }
    
    // 判断条件:如果传入的权限码是string则转化成数组
    if (typeof value === 'string') {
      value = [value]
    }

    /**
     * 判断条件
     *  -修饰符为 every时 value数组只要有一个元素不存在access权限集内,隐藏元素
     *  -修饰符为 some或者没有时,value数组所有元素都不存在access权限集内,隐藏元素
     */ 
    if (
      (
        modifiers.every &&
        value.some(v => !access.includes(v))
      ) ||
      (
        !modifiers.every &&
        value.every(v => !access.includes(v))
      )
    ) {
      remove(el)
    }
  }
}

v-auth 同一个组件页面在多个菜单中被使用,所以要根据菜单的不同做按钮控制

eg:设备列表页面,在 生产设备、感控设备、PLC、SCADA、网关等五个菜单中被使用,那么不能通过值来判断是否有权限,而是通过菜单类型判断。

import Vue from 'vue'
import { MENU_AUTH_OBJ } from '@/const'
/*或者直接使用项目组提供的包,直接使用他的v-auth*/
export default ()=>{
  Vue.directive('auth',{
    inserted:(el,binding,vNode)=>{
      let authList = ['200','201']
      // 根据接口返回的code存储在store中
      authList = vNode.context.$store.state.deviceMgmt.accessList||[]
      
      let arg = binding.arg // 参数arg,可以是动态的
      // 已经知道这五个菜单公用了一个页面:
      let deviceAuthArr = ['menuProduction','menuInduction','menuPlc','menuScada','menuGateway',]
      let flag = deviceAuthArr.some(v=>v==binding.arg)
      // 有arg参数,且是设备的五个菜单时候,才走这个逻辑
      if(arg&&flag){
        deviceAuthArr.forEach(v=>{
          if(arg == v){
            // 每一个菜单都设置了一个code,eg:model.device-plc.edit,判断authList中是否有这个code
            if(!authList.includes(MENU_AUTH_OBJ[v].auth)){
              el.parentNode.removeChild(el)
            }
          }
        })

        // 其他场景
      }else {
        if(authList.includes(binding.value)){

        }else {
          el.parentNode.removeChild(el)
        }
      }
    }
  })
}
// 使用
<div class="table-top-btns" v-if="pageOrigin == 'modelMeasureAttr'&&!isReadOnlyCalc" v-auth:[$route.params.menuType]="canEdit">

="canEdit"已经不用了,我们通过arg判断过了,不需要值判断了。

加载更多

import Vue from 'vue'

export default () => {
  Vue.directive('loadmore', {
    bind (el, binding) {
      console.log('指令el111:', el)
      // 获取滚动页面DOM
      const SCROLL_DOM = el.querySelector('.el-select-dropdown .el-select-dropdown__wrap')
      const SCROLL_DOM_ALl = el.querySelector('.el-select-dropdown .el-select-dropdown__wrap .el-select-dropdown__list')
      SCROLL_DOM.addEventListener('scroll', () => {
        console.log('scroll')

        console.log('1', SCROLL_DOM.clientHeight)
        console.log('2', SCROLL_DOM.scrollTop)
        console.log('3', SCROLL_DOM.scrollHeight)
        console.log('4', SCROLL_DOM_ALl.clientHeight)

        if (SCROLL_DOM.scrollTop + SCROLL_DOM.clientHeight >= SCROLL_DOM.scrollHeight) {
          console.log('加载更多')
          // 将滚动行为告诉组件
          binding.value()
        }
      })
    }
  })
}

  • 10
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值