自定义指令

218 阅读1分钟

注意事项

  • 自定义指令必须v开头,驼峰命名

全写示例代码

<script setup lang="ts">
import Test from './Test.vue'
import { Directive, DirectiveBinding } from 'vue'

type Dir = {
  bgc: string
}

const vMove: Directive = {
  created() {
    console.log('created')
  },
  beforeMount() {
    console.log('beforeMount')
  },
  mounted(...args: Array<any>) {
    // 常用
    console.log(args)
    console.log('mounted')
  },
  // mounted(el: HTMLElement, dir: DirectiveBinding<Dir>) {
  //   console.log(dir)
  //   console.log('mounted')
  // },
  beforeUpdate() {
    console.log('beforeUpdate')
  },
  updated() {
    // 常用
    console.log('updated')
  },
  beforeUnmount() {
    console.log('beforeUnmount')
  },
  unmounted() {
    // 常用
    console.log('unmounted')
  },
}
</script>

<template>
  <Test v-move:canshu.modifier1.modifier2="123" />
</template>

打印结果如下:

  • 参数1:dom元素
  • 参数2:指令接收到的参数、修饰符、值等的集合
    • arg:参数
    • modifiers:修饰符组成的对象
    • value:接收的值
  • 参数3:新的vnode
  • 参数4:旧的vnode

image.png

简写示例代码

如果只关心mountedupdated钩子函数,自定义指令可以使用函数简写

type Dir = {
  bgc: string
}
const vMove = (el: HTMLElement, dir: DirectiveBinding<Dir>) => {
  
}

拖拽元素代码实现

注意:被拖拽的元素要 绝对定位

<script setup lang="ts">
import Test from './Test.vue'
import { Directive, DirectiveBinding } from 'vue'

const vMove: Directive = (el: HTMLElement, dir: DirectiveBinding) => {
  let moveElement: HTMLElement = el as HTMLDivElement
  const mousedown = (e: MouseEvent) => {
    const X = e.clientX - moveElement.offsetLeft
    const Y = e.clientY - moveElement.offsetTop
    const move = (e: MouseEvent) => {
      moveElement.style.left = e.clientX - X + 'px'
      moveElement.style.top = e.clientY - Y + 'px'
    }
    document.addEventListener('mousemove', move)
    document.addEventListener('mouseup', () => {
      document.removeEventListener('mousemove', move)
    })
  }
  moveElement.addEventListener('mousedown', mousedown)
}
</script>

<template>
  <Test v-move />
</template>

<style lang="scss" scoped></style>