vue3的自定义指令

Posted 前端纸飞机

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了vue3的自定义指令相关的知识,希望对你有一定的参考价值。

除了 Vue 内置的一系列指令 (比如 v-model 或 v-show) 之外,Vue 还允许你注册自定义的指令 (Custom
Directives)。

1.自定义指令的目的和简单介绍

自定义指令主要是为了重用涉及普通元素的底层 DOM 访问的逻辑。
一个自定义指令由一个包含类似组件生命周期钩子的对象来定义。钩子函数会接收到指令所绑定元素作为其参数。
举例:

在某个场景下,需要一进入页面或者打开某个弹窗就聚焦到指定的输入框。
局部的写法:

<script setup>
const vFocus = 
  created(el, binding, vnode) 
  ,
  beforeMount(el, binding, vnode) 
  ,
  mounted(el) 
    el.focus()
  ,
  beforeUpdate(a,b,c,prevNode)  //! 第四个参数 prevNode 只在beforeUpdate和updated才有!
  ,
  updated() ,
  beforeUnmount() 
    // 当指令绑定的元素 的父组件销毁前调用。  <简单讲,指令元素的父组件销毁前调用>
  ,
  unmounted() ,// 当指令与元素解除绑定且父组件已销毁时调用。

</script>

<template>
  <input v-focus>
</template>

全局的写法:

import  createApp  from 'vue'
const app = createApp(App)
app.directive('focus',
  created(el, binding, vnode) 
  ,
  beforeMount(el, binding, vnode) 
  ,
  mounted() 
  	el.focus()
  ,
  beforeUpdate(a,b,c,prevNode)  //! 第四个参数 prevNode 只在beforeUpdate和updated才有!
  ,
  updated() ,
  beforeUnmount() 
    // 当指令绑定的元素 的父组件销毁前调用。  <简单讲,指令元素的父组件销毁前调用>
  ,
  unmounted() ,// 当指令与元素解除绑定且父组件已销毁时调用。
)

使用全局注册需注意得写在mount(‘#app’)之前,否则会报错

我门可以发现对比vue2来看vue3里自定义指令似乎在生命周期这块发生了某些变化,下面我们来看看具体的。
注意:后面的示例都用局部的自定义指令来讲解。

2.对比vue2自定义指令的生命周期

vue2自定义指令生命周期

  • bind: function () ,
  • inserted: function () ,
  • update: function () ,
  • componentUpdated: function () ,
  • unbind: function ()

vue3自定义组件生命周期

  • created:在绑定元素的 attribute 或事件监听器被应用之前调用。在指令需要附加在普通的 v-on
    事件监听器调用前的事件监听器中时,这很有用。
  • beforeMount:当指令第一次绑定到元素并且在挂载父组件之前调用。
  • mounted:在绑定元素的父组件被挂载后调用。
  • beforeUpdate:在更新包含组件的 VNode 之前调用。
  • updated:在包含组件的 VNode 及其子组件的 VNode 更新后调用。
  • beforeUnmount:在卸载绑定元素的父组件之前调用
  • unmounted:当指令与元素解除绑定且父组件已卸载时,只调用一次。

这些生命周期都会接受以下几个参数:

el, binding, vnode, prevVnode

他们分别代表什么意思呢?

el:指令绑定到的元素。这可以用于直接操作 DOM。
binding:一个对象,包含以下属性。

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

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

这样看可能抽象了点,我们在指令的mounted里打印下这4个参数,可见:

<script setup>
const vFocus = 
  created(el, binding, vnode) 
  ,
  beforeMount(el, binding, vnode) 
  ,
  mounted(el,binding, vnode,prevVnode) 
    console.log('el--',el)
    console.log('binding-',binding)
    console.log('vnode-',vnode)
    console.log('prevVnode-',prevVnode)
    console.log()
    el.focus()
  ,
  beforeUpdate(a,b,c,prevNode)  //! 第四个参数 prevNode 只在beforeUpdate和updated才有!
  ,
  updated() ,
  beforeUnmount() 
    // 当指令绑定的元素 的父组件销毁前调用。  <简单讲,指令元素的父组件销毁前调用>
  ,
  unmounted() ,// 当指令与元素解除绑定且父组件已销毁时调用。

</script>

3.举两个栗子

我们主要看elbinding
我们通过自定义指令来画一个固定宽高和背景色的方块吧!

//name:自定义参数,hqg:自定义修饰符
<div v-myDirective:name.hqg="background: '#ccc', width: '200px', height: '200px'">
  这是一个div
</div>
const vMyDirective = 
  mounted(el,binding, vnode,prevVnode) 
    console.log('binding',binding)
    el.style.background = binding.value.background
    el.style.width = binding.value.width
    el.style.height = binding.value.height
  ,

最后注意

只有当所需功能只能通过直接的 DOM 操作来实现时,才应该使用自定义指令。其他情况下应该尽可能地使用 v-bind 这样的内置指令来声明式地使用模板,这样更高效,也对服务端渲染更友好。

以上是关于vue3的自定义指令的主要内容,如果未能解决你的问题,请参考以下文章

vue3的自定义指令

vue3的自定义指令

vue3的自定义指令

vue3.0 如何自定义指令

vue3.0 如何自定义指令

vue3.0 如何自定义指令