vue3 自定义指令

  Vue内部封装好的指令是内置指令,如v-if、v-model等,方便我们对dom元素完成某项操作。而自定义指令就是根据自身要求,自己编写且封装好的一些指令,有较高的灵活性。不过自定义指令也需要以v-开头。本文主要重点学习一下Vue3中自定义指令如何使用?

主要应用场景: 防抖、图片懒加载、一键 Copy的功能、拖拽、页面水印、权限校验、输入框自动聚焦、相对时间转换、下拉菜单

自定义指令

  • 注册自定义指令
    • 全局注册
    • 局部注册
  • 钩子函数及其参数
    • 钩子函数
    • 参数详解
  • 指令简写

注册自定义指令

  在Vue中,使用一个组件我们需要先注册再调用,简单点就是先声明再调用。自定义指令也是如此。组件可以注册为全局组件和局部组件,同理自定义指令也可以分为全局注册和局部注册。
  使用自定义指令:

<template>
	<input type="text" v-focus />
template>

全局注册

  全局注册自定义指令时,该自定义指令可以在任一组件上调用,代码复用率得到提高。
  示例代码:

// main.js
import { createApp } from "vue";
import App from "./App.vue";
// 创建根节点
const app = createApp(App);
app.directive("focus", {
  created(el, binding, vnode, prevVnode) {},
  beforeMount(el, binding, vnode, prevVnode) {},
  mounted(el, binding, vnode, prevVnode) {},
  beforeUpdate(el, binding, vnode, prevVnode) {},
  updated(el, binding, vnode, prevVnode) {},
  beforeUnmount(el, binding, vnode, prevVnode) {},
  unmounted(el, binding, vnode, prevVnode) {},
});
// 挂载渲染根节点
app.mount("#app");

  在上述代码中,可以借助Vue提供的directive方法来全局注册自定义指令。directive方法接收两个参数:指令名称和指令钩子函数对象
  批量注册指令:

// focus.js
export default const vCopy = { // 钩子函数
}
...

//  directives/index.js
import copy from './copy'
import longpress from './longpress'
// 自定义指令
const directives = {
  	copy,
  	longpress,
}
 
export default {
	// install方法是传入一个组件实例。
	install(Vue) {
		// 遍历自定义指令并使用Vue的directive方法全局注册指令
    	Object.keys(directives).forEach((key) => {
      	Vue.directive(key, directives[key])
    	})
 	 }
}

// main.js
import { createApp } from "vue";
import App from "./App.vue";
import Directives from './directives'
const app = createApp(App);
Vue.use(Directives)

局部注册

  全局注册自定义指令是因为该自定义指令要作用于多个不同组件,但在某些特定情况下自定义指令只作用于一个组件,此时局部注册该指令更为合适。

<template>
</template>
<script setup>
	const vFocus = {
	  created(el, binding, vnode, prevVnode) {},
	  beforeMount(el, binding, vnode, prevVnode) {},
	  mounted(el, binding, vnode, prevVnode) {},
	  beforeUpdate(el, binding, vnode, prevVnode) {},
	  updated(el, binding, vnode, prevVnode) {},
	  beforeUnmount(el, binding, vnode, prevVnode) {},
	  unmounted(el, binding, vnode, prevVnode) {},
	}
</script>

  在Vue3中,以小写字母v开头的驼峰命名的变量都可以作为一个自定义指令使用,比如上段代码中vFocus就可以在模板中通过v-focus的指令形式使用。

钩子函数及其参数

钩子函数

  在Vue3中,自定义指令中的钩子函数几乎和组件的生命周期钩子函数一样,这也是和Vue2中自定义指令的重大区别之一。
  从上述代码可以知道,在Vue3中,自定义指令的钩子函数分别为:

钩子函数 执行时机
created 在绑定元素的 attribute 前或事件监听器应用前调用。
beforeMount 在元素被插入到 DOM 前调用。
mounted 在绑定元素的父组件及他自己的所有子节点都挂载完成后调用。
beforeUpdate 绑定元素的父组件更新前调用。
updated 在绑定元素的父组件及他自己的所有子节点都更新后调用。
beforeUnmount 绑定元素的父组件卸载前调用。
unmounted 绑定元素的父组件卸载后调用。

参数详解

  Vue2与Vue3中,钩子函数的参数不变,包括 el, binding, vnode, prevVnode

  • el:指令绑定到的元素。这可以用于直接操作 DOM。
  • binding:一个对象,包含以下属性
属性 含义
value 传递给指令的值。例如在 v-my-directive=“1 + 1” 中,值是 2。
oldValue 之前的值,仅在 beforeUpdate 和 updated 中可用。无论值是否更改,它都可用。
arg 传递给指令的参数 (如果有的话)。例如在 v-my-directive:foo 中,参数是 “foo”。
modifiers 一个包含修饰符的对象 (如果有的话)。例如在 v-my-directive.foo.bar 中,修饰符对象是 { foo: true, bar: true }。
instance 使用该指令的组件实例。
dir 指令的定义对象。
  • vnode:代表绑定元素的底层 VNode。

  • prevNode:之前的渲染中代表指令所绑定元素的 VNode。仅在 beforeUpdate 和 updated 钩子中可用。

指令简写

  Vue3中,自定义提供了很多的钩子函数,但是实际开发中不需要使用这么多钩子函数。所以与Vue2相同,Vue3提供了自定义指令的简写形式。
  示例代码:

<template>
	<img alt="Vue logo" src="./assets/logo.png" />
  	<div v-focus="'#ccc'">
    	<input type="text" />
    	<div>{{ message }}div>
  	div>
  	<button @click="changeMsg">修改messagebutton>
template>

<script setup>
	import { DirectiveBinding, ref } from "vue";
	let message = ref<string>("小猪课堂");
	const changeMsg = () => {
	  	message.value = "张三";
	};
	// 在模板中启用 v-focus
	const vFocus = (el: HTMLElement, binding: DirectiveBinding) => {
		// 这会在 `mounted` 和 `updated` 时都调用
		el.style.backgroundColor = binding.value;
	};
script>

  上段代码中我们省去了自定义指令中的所有钩子函数,直接简写为了一个箭头函数,该函数在 mounted 和 updated 时都调用。我们在div上绑定了自定义指令,并且传入了一个颜色参数。

后面的文章主要是学习 自定义指令的案例

你可能感兴趣的:(javascript,vue.js,前端)