vue3+vite+ts 自定义指令详解

  1. directive-自定义指令(属于破坏性更新)

    Vue中有v-if,v-for,v-bind,v-show,v-model 等等一系列方便快捷的指令 今天一起来了解一下vue里提供的自定义指令

Vue3指令的钩子函数
created 元素初始化的时候
beforeMount 指令绑定到元素后调用 只调用一次
mounted 元素插入父级dom调用
beforeUpdate 元素被更新之前调用
update 这个周期方法被移除 改用updated
beforeUnmount 在元素被移除前调用
unmounted 指令被移除后调用 只调用一次
Vue2 指令 bind inserted update componentUpdated unbind

  1. 在setup内定义局部指令
    但这里有一个需要注意的限制:必须以 vNameOfDirective 的形式来命名本地自定义指令,以使得它们可以直接在模板中使用。
<template>
  <button @click="show = !show">开关{{show}} ----- {{title}}</button>
  <Dialog  v-move-directive="{background:'green',flag:show}"></Dialog>
</template>
 
const vMoveDirective: Directive = {
  created: () => {
    console.log("初始化====>");
  },
  beforeMount(...args: Array<any>) {
    // 在元素上做些操作
    console.log("初始化一次=======>");
  },
  mounted(el: any, dir: DirectiveBinding<Value>) {
    el.style.background = dir.value.background;
    console.log("初始化========>");
  },
  beforeUpdate() {
    console.log("更新之前");
  },
  updated() {
    console.log("更新结束");
  },
  beforeUnmount(...args: Array<any>) {
    console.log(args);
    console.log("======>卸载之前");
  },
  unmounted(...args: Array<any>) {
    console.log(args);
    console.log("======>卸载完成");
  },
};

3.生命周期钩子参数详解

  • 第一个 el 当前绑定的DOM 元素

  • 第二个 binding

    instance:使用指令的组件实例。
    value:传递给指令的值。例如,在 v-my-directive=“1 + 1” 中,该值为 2。
    oldValue:先前的值,仅在 beforeUpdate 和 updated 中可用。无论值是否有更改都可用。
    arg:传递给指令的参数(如果有的话)。例如在 v-my-directive:foo 中,arg 为 “foo”。
    modifiers:包含修饰符(如果有的话) 的对象。例如在 v-my-directive.foo.bar 中,修饰符对象为 {foo: true,bar: true}。
    dir:一个对象,在注册指令时作为参数传递。例如,在以下指令中

  • 第三个 当前元素的虚拟DOM 也就是Vnode

  • 第四个 prevNode 上一个虚拟节点,仅在 beforeUpdate 和 updated 钩子中可用

4.函数简写
你可能想在 mounted 和 updated 时触发相同行为,而不关心其他的钩子函数。那么你可以通过将这个函数模式实现

<template>
   <div>
      <input v-model="value" type="text" />
      <DVue v-move="{ background: value }"></DVue>
   </div>
</template>
   
<script setup lang='ts'>
import DVue from './components/D.vue'
import { ref, Directive, DirectiveBinding } from 'vue'
let value = ref<string>('')
type Dir = {
   background: string
}
const vMove: Directive = (el, binding: DirectiveBinding<Dir>) => {
   el.style.background = binding.value.background
}
</script>

5.示例Demo
1.按钮权限按钮

<template>
    <div style="margin-top: 20px">
        <el-button v-has-show="'shop:create'">创建</el-button>
        <el-button v-has-show="'shop:edit'">编辑</el-button>
        <el-button v-has-show="'shop:delete'">删除</el-button>
    </div>
</template>
<script setup lang="ts">
import type { Directive } from "vue"
localStorage.setItem("userId", "myYYDS")
// mock后台返回的数据
const permission = [
    "myYYDS:shop:edit",
    "myYYDS:shop:create",
    "myYYDS:shop:delete",
]
const userId = localStorage.getItem("userId") as string
const vHasShow: Directive<HTMLElement, string> = (el, bingding) => {
    if (!permission.includes(userId + ":" + bingding.value)) {
        el.style.display = "none"
    }
}
</script>
<style scoped lang="scss"></style>

  1. 移动 自定义拖拽指令
    在这里插入图片描述
<template>
    <div style="margin-top: 20px" v-move class="box">
        <div class="header"></div>
        <div>我移动啦</div>
    </div>
</template>
<script setup lang="ts">
import type { Directive } from "vue"
const vMove: Directive<any, void> = (el: HTMLElement) => {
    let moveElement: HTMLDivElement = el.firstElementChild as HTMLDivElement
    const mouseDown = (e: MouseEvent) => {
        let X = e.clientX - el.offsetLeft
        let Y = e.clientY - 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)
        })
    }
    moveElement.addEventListener("mousedown", mouseDown)
}
</script>
<style scoped lang="scss">
.box {
    position: fixed;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    width: 200px;
    height: 200px;
    border: 1px solid #ccc;
    .header {
        height: 20px;
        background: black;
        cursor: move;
    }
}
</style>

3.图片懒加载

<template>
    <div v-for="item in arr">
        <img height="500" :data-index="item" v-lazy="item" width="360" alt="" />
    </div>
</template>
<script setup lang="ts">
import { Directive } from "vue"

// vite 提供的方法可以引入全部的图片
// glob:是懒加载的模式
// globEager 静态加载全部
let imageList: Record<string, { default: string }> = import.meta.glob(
    "../../assets/images/*.*",
    { eager: true },
)
let arr = Object.values(imageList).map((v) => v.default)

let vLazy: Directive<HTMLImageElement, string> = async (el, bingding) => {
    const def = await import("../../assets/vue.svg")
    el.src = def.default
    // 判断元素是否是可视区域
    const observer = new IntersectionObserver((enr) => {
        if (enr[0].intersectionRatio) {
            setTimeout(() => {
                el.src = bingding.value
            }, 2000)
        }
    })
    observer.observe(el)
}
</script>
<style scoped lang="scss"></style>

在这里插入图片描述
在这里插入图片描述

相关推荐

  1. 详解Vue定义指令

    2024-05-10 06:22:01       40 阅读
  2. Vue3.2 定义指令详解与实战

    2024-05-10 06:22:01       39 阅读
  3. vue3定义指令

    2024-05-10 06:22:01       36 阅读
  4. vue3定义指令

    2024-05-10 06:22:01       41 阅读
  5. VUE3 定义指令

    2024-05-10 06:22:01       18 阅读
  6. vue3定义指令

    2024-05-10 06:22:01       16 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-05-10 06:22:01       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-05-10 06:22:01       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-05-10 06:22:01       19 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-05-10 06:22:01       20 阅读

热门阅读

  1. win7下安装python,matplotlib,numpy

    2024-05-10 06:22:01       13 阅读
  2. 如何利用AI提高内容生产效率?

    2024-05-10 06:22:01       11 阅读
  3. 揭秘:深度学习与自然语言处理的本质差异

    2024-05-10 06:22:01       13 阅读
  4. HTTP协议:通信机制、特点及实践应用

    2024-05-10 06:22:01       13 阅读
  5. Vue从入门到精通-13-Vue-router路由

    2024-05-10 06:22:01       11 阅读
  6. 代码随想录算法训练营第四十四天

    2024-05-10 06:22:01       13 阅读
  7. GIS找工作:天津测绘院24届春招Offer面经

    2024-05-10 06:22:01       17 阅读
  8. Vue 生命周期

    2024-05-10 06:22:01       12 阅读
  9. Android手机应用开发工程师应届生学习大纲

    2024-05-10 06:22:01       14 阅读
  10. 学习记录之数学表达式(4)

    2024-05-10 06:22:01       13 阅读