Vue3系列(十五)之自定义指令 directive

207 阅读2分钟

Vue3自定义指令提供的钩子

vue3含义
created在绑定元素的attribute属性前或者事件监听器应用前调用
beforeMount在元素插入到DOM前调用
mounted在绑定元素的父组件及他自己所有的子节点都挂载完成后调用
beforeUpdate绑定元素的父组件更新前调用
updated在绑定元素的父组件及他自己所有的子节点都更新完成后调用
beforeUnmount绑定元素的父组件卸载前调用
unmounted绑定元素的父组件卸载后调用

如何在setup中定义局部自定义指令

在setup模式中定义自定义指定时,需要以 vNameDirective 的形式来命名自定义指令,这样就可以直接在页面上直接使用

<template>
  <div style="width: 200px;height: 200px" v-style-directive="{background:'green',flag:show}">
  </div>
</template>
import { Directive, DirectiveBinding } from 'vue';

type StyleObject = {
  background: string
}

const vStyleDirective: Directive = {
  created: () => {
    console.log("初始化====>");
  },
  beforeMount(...args: Array<any>) {
    // 在元素上做些操作
    console.log("初始化一次=======>");
  },
  mounted(el: any, dir: DirectiveBinding<StyleObject>) {
    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("======>卸载完成");
  }
}

image.png

自定义指令钩子函数的参数

image.png

  • el:指令绑定的元素。可用于直接操作dom
  • binding:一个对象,包含以下属性
属性介绍
value传递给指令的值
oldValue之前的值,仅在 beforeUpdate 和 updated 中可用
arg传递给指令的参数。例如在 v-my-directive:foo 中,参数是 "foo"
modifiers一个包含修饰符的对象 (如果有的话)。例如在 v-my-directive.foo 中,修饰符对象是 {foo: true}
instance使用该指令的组件实例
dir指令的定义对象
  • vNode:绑定元素的底层虚拟DOM,也就是vNode
  • preVNode:之前的渲染中代表指令所绑定元素的 VNode。仅在 beforeUpdate 和 updated 钩子中可用

简易自定义指令

自定义指令允许定义为一个函数,但该指令只会在 mountedupdated生命周期中触发

<template>
  <div style="width: 200px;height: 200px" v-style-directive="{background:'green',flag:show}">
  </div>
</template>
type StyleObject = {
  background: string
}

const vStyle: Directive = (el, binding: DirectiveBinding<StyleObject>) => {
  el.style.background = binding.value.background
}

全局自定义指令

如果想要定义一个全局的自定义指令,我们可以在mian.ts中进行定义

import { createApp } from 'vue'

const app = createApp({}) 

// 使 v-mydirective 在所有组件中都可用
app.directive('mydirective', (el, binding) => { 
    /* ... */
    // 这会在 `mounted` 和 `updated` 时都调用
})

// 或者
app.directive('mydirective', { 
    created(el, binding, vnode, prevVnode) {}
    /* ... */
})