12

vue3+TS 自定义指令:长按触发绑定的函数 - bbigger004

 1 year ago
source link: https://www.cnblogs.com/bbigger004/p/17012784.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

vue3+TS 自定义指令:长按触发绑定的函数

偶然间看到一个在vue2中写的长按触发事件的自定义指定,想着能不能把他copy到我的vue3项目中呢。

编写自定义指令时遇到的几个难点

1.自定义指令的类型

在ts中写任何东西都要考虑到类型的问题,自定义指令的类型问题依然存在

2.在ts中使用setTimeout() 函数

setTimeout()函数的默认返回值是一个随机的number ,这个number 代表了这个计时器的唯一id,但是并不能直接将其类型定义为number 否则会出现报错。

3.自定义指令的传参问题

我这里的传参方法只做参考,写的很不规范。具体的好多传参的方法请自行搜索

这个是我自己编写的长按触发绑定的函数
directives/longPress.ts

import { ObjectDirective } from 'vue'

const LongPress: ObjectDirective = {
  // 组件mounted时执行指令
  mounted(el, binding, vNode) {
    // 确保提供的表达式是函数
    if (typeof binding.value !== 'function') {
      // // 将警告传递给控制台
      let warn = `[longpress:] provided expression '${binding.value}' is not afunction, but has to be `
      console.log(warn)
    } else {
      console.table({ el, binding, vNode })
      let timer: ReturnType<typeof setTimeout> | null = null  //定义空 定时器
      const start = (e: MouseEvent | TouchEvent) => {
        console.log(e)
        //下列事件不执行1.不是鼠标左键2.单击事件  (3.没有传入长按时间 ?? 有默认)
        if ((<MouseEvent>e).button !== 0 && e.type === 'click') {
          return
        }
        if (timer == null) {
          timer = setTimeout(() => {
            handler()
          }, Number(binding.arg) * 1000 ?? 0.5 * 10000) //默认长按0.5秒执行绑定的函数
        }
      }
      const cancel = () => {
        if (timer !== null) {
          clearTimeout(timer)
          console.log(timer);//定时器默认返回一个随机的number 这个number的值是这个定时器的id
          timer = null
        }
      }
      const handler = () => {
        binding.value()
      }
      // 添加事件监听器
      el.addEventListener('mousedown', start)
      el.addEventListener('touchstart', start)
      // 取消计时器
      el.addEventListener('click', cancel)
      el.addEventListener('mouseout', cancel)
      el.addEventListener('touchend', cancel)
      el.addEventListener('touchcancel', cancel)
    }
  },
}

export default LongPress

在main.ts中引入 作为全局自定义指令

import { createApp } from 'vue'
import App from './App.vue'
import LongPress from './directives/longpress'

const app = createApp(App)
app.directive('longPress',LongPress)
app.mount('#app')

在组件中使用
这里的v-longPress 便是自定义指令,其中此处的参数传递方法仅供参考

<template>
  <div>
    <button v-longPress = 'longFunc,1' >longPress</button>
  </div>
</template>

<script setup lang="ts">
const longFunc = () => {
  console.log('click long btn');
  alert('click long btn')
}
</script>

<style scoped>

</style>

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK