按钮指令

2023/6/6 vue

# 按钮指令(文件位置产品 th-admin中directive)

# 1. v-debounce 防抖指令使用

  • 防止用户重复多次点击
  • v-debounce 指令接受的必须是一个函数,可以指令后方括号设置时间(毫秒),默认500毫秒

# 使用示例

<template>
  <div>
    <!-- 默认500毫秒的防抖时间 -->
    <el-button v-debounce="onClickSave">保存</el-button>

    <!-- 自定义2000毫秒防抖时间 -->
    <el-button v-debounce:[2000]="onClickSave">保存</el-button>

    <!-- 带参数使用 -->
    <el-button v-debounce="() => onClickSave('自定义参数')">保存</el-button>
  </div>
</template>

<script>
export default{
   methods: {
    onClickSave () {
      console.log('点击了保存按钮')
    }
  }
}
</script>

# 源码

const debounce = {
  inserted(el, binding) {
    const { value, arg = 500 } = binding
    if (typeof value !== 'function') {
      throw new Error(`回调必须是一个函数`)
    }
    let timer = null
    el.__handleClick__ = function () {
      if (timer) {
        clearInterval(timer)
      }
      timer = setTimeout(() => {
        value()
      }, arg)
    }
    el.addEventListener('click', el.__handleClick__)
  },
  unbind (el) {
    el.removeEventListener('click', el.__handleClick__)
  }
}

# 2. v-throttle 节流指令使用

  • 限制用户点击频率
  • v-throttle 指令接受的必须是一个函数,可以指令后方括号设置时间(毫秒),默认500毫秒

# 使用示例

<template>
  <div>
    <!-- 默认1000毫秒的节流时间 -->
    <el-button v-throttle="onClickSend">发射子弹</el-button>

    <!-- 自定义2000毫秒节流时间 -->
    <el-button v-throttle:[2000]="onClickSend">发射子弹</el-button>

    <!-- 带参数使用 -->
    <el-button v-throttle="() => onClickSend('自定义参数')">发射子弹</el-button>
  </div>
</template>

<script>
export default{
  methods: {
    onClickSend () {
      console.log('发射子弹')
    }
  }
}
</script>

# 源码

const throttle = {
  inserted(el, binding) {
    const { value, arg = 1000 } = binding
    if (typeof value !== 'function') {
      throw new Error(`回调必须是一个函数`)
    }
    let timer = null
    el.__handleClick__ = function () {
      if (timer) {
        clearInterval(timer)
      }
      if (!el.disabled) {
        el.disabled = true
        value()
        timer = setTimeout(() => {
          el.disabled = false
        }, arg)
      }
    }
    el.addEventListener('click', el.__handleClick__)
  },
  unbind (el) {
    el.removeEventListener('click', el.__handleClick__)
  }
}

# 3. v-longpress 长按指令使用

  • 用户在点击按钮达到时间后触发
  • v-longpress 指令接受的必须是一个函数,可以指令后方括号设置时间(毫秒),默认500毫秒

# 使用示例

<template>
  <div>
    <!-- 默认2000毫秒的长按时间后触发 -->
    <el-button v-longpress="onClickSend">蓄力发射</el-button>

    <!-- 自定义1000毫秒长按时间后触发 -->
    <el-button v-longpress:[1000]="onClickSend">蓄力发射</el-button>

    <!-- 带参数使用 -->
    <el-button v-longpress="() => onClickSend('自定义参数')">蓄力发射</el-button>
  </div>
</template>

<script>
export default{
  methods: {
    onClickSend () {
      console.log('发射子弹')
    }
  }
}
</script>

# 源码

const longpress = {
  inserted(el, binding) {
    const { value, arg = 2000 } = binding

    let pressTimer = null
    // 执行函数
    const start = (e) => {
      if (e.button) {
        if (e.type === 'click' && e.button !== 0) {
          return
        }
      }
      if (pressTimer === null) {
        pressTimer = setTimeout(() => {
          handler(e)
        }, arg)
      }
    }
    // 取消计时器
    const cancel = () => {
      if (pressTimer !== null) {
        clearTimeout(pressTimer)
        pressTimer = null
      }
    }

    // 运行函数
    const handler = (e) => {
      value(e)
    }

    // 添加事件监听器
    el.addEventListener('mousedown', start)
    el.addEventListener('touchstart', start)
    // 取消计时器
    el.addEventListener('click', cancel)
    el.addEventListener('mouseout', cancel)
    el.addEventListener('touchend', cancel)
    el.addEventListener('touchcancel', cancel)
  }
}