vue3笔记十二(自定义指令directive)

1、自定义指令

vue3指令的钩子函数

  • created
  • beforeMount
  • mounted
  • beforeUpdate
  • updated
  • beforeUnmount
  • unmounted

2、简单使用

<template>
  <button @click="change">change</button>
  {{num}}
  <Dialog v-model="flag" v-move:foo.aaa="{background: 'red'}"/>
</template>

<script setup lang="ts">
import Dialog from './dialog.vue'
import {Directive} from "vue";

const flag = ref<boolean>(true)
const num = ref(1)
const change = () => {
  num.value++
  setTimeout(() => {
    flag.value=!flag.value
  }, 3000)
}

const vMove:Directive = {
  created: () => {
    console.log('初始化--------')
  },
  beforeMount: (...args:Array<any>) => {
    console.log('挂载前--------', args)
  },
  mounted: () => {
    console.log('挂载--------')
  },
  beforeUpdate: () => {
    console.log('更新前--------')
  },
  updated: () => {
    console.log('更新--------')
  },
  beforeUnmount: () => {
    console.log('销毁前--------')
  },
  unmounted: () => {
    console.log('销毁--------')
  },
}
</script>

3、生命周期钩子参数

vue3笔记十二(自定义指令directive)_第1张图片
第一个el为当前绑定的DOM元素
第二个binging

  • instance:使用指令的组件实例
  • value:传递给指令的值。如上为{background: ‘red’}
  • oldValue:之前的值,仅在beforeUpdate 和 updated 中可用
  • arg:传递给指令的参数。如上foo
  • modifiers:修饰符对象。如上{aaa: true}
  • dir:一个对象,在注册指令时作为参数传递

第三个为当前元素的虚拟DOM,也就是Vnode
第四个为上一个虚拟节点,仅在beforeUpdate 和 updated 中可用

4、指令函数简写

仅需在mounted和updated时触发事件,而无需其他钩子函数。那么可以通过以下函数模式实现

<template>
  <input type="text" v-model="value">
  <Dialog v-move:foo.aaa="{background: value}"/>
</template>

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

const value = ref<string>('')

type Dir = {
  background: string
}

const vMove:Directive = (el, binding: DirectiveBinding<Dir>) => {
  el.style.background = binding.value.background
}
</script>

5、自定义拖拽案例

<template>
  <h1>根元素</h1>
  <div style="position: relative">
    <div v-move style="background: red; width: 100px; height: 100px; position: absolute"></div>
  </div>
</template>

<script setup lang="ts">
import {Directive} from "vue";

const vMove:Directive = {
  mounted: (el: HTMLElement) => {
    const mouseDown = (e: MouseEvent) => {
      let X = e.clientX - el.offsetLeft
      let Y = e.clientY - el.offsetTop
      console.log('点位位置相对文档的水平、垂直坐标', e.clientX, e.clientY)
      console.log('点击位置相对于父容器的水平、垂直坐标', e.offsetX, e.offsetY)
      console.log('点击位置相对父元素偏移位置', el.offsetLeft, el.offsetTop)
      const move = (e: MouseEvent) => {
        el.style.left = e.clientX - X + 'px'
        el.style.top = e.clientY - Y + 'px'
      }
      document.addEventListener('mousemove', move)
      document.addEventListener('mouseup', () => {
        document.removeEventListener('mousemove', move)
      })
    }
    el.addEventListener('mousedown', mouseDown)
  }
}
</script>

<style scoped>
.wrap {
  width: 200px;
  height: 200px;
  background-color: #f9f9f9;
}
</style>

原文链接:https://xiaoman.blog.csdn.net/article/details/123228132

你可能感兴趣的:(vue3笔记,vue.js,前端,typescript)