当前位置: 首页 > news >正文

vue3自定义指令(directive)

介绍

在vue中除了一些内置的指令,比如v-model等之外,也可以自己注册自定义指令。

在vue中重用代码的方式有组件组合式函数。组件一般是用于构建模式,也就是界面,而组合式函数注重于状态的逻辑。

而自定义指令是为了重用涉及到普通元素的底层DOM访问的逻辑。

一个自定义指令是由一个类似组件生命周期函数的对象来定义的,钩子函数会接收到指令绑定的元素作为参数。

例子:一个输入框,一进页面就能自动获取焦点。

<script setup>
// 在模板中启用 v-focus
const vFocus = {
  mounted: (el) => el.focus()
}
</script>

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

这里的参数el是DOM元素,在script setup模式下会认为以小写字母v开头的驼峰命名法是一个自定义指令。

在一个没有script setup的情况下,使用directive进行注册

export default {
  setup() {
    /*...*/
  },
  directives: {
    // 在模板中启用 v-focus
    focus: {
      mounted(el) {
		el.focus();
      }
    }
  }
}

也可以将一个自定义指令进行全局注册

const app = createApp({})

// 使 v-focus 在所有组件中都可用
app.directive('focus', {
  /* ... */
})

指令钩子

一个指令的定义对象可以有多个钩子函数 (都是可选的):

const myDirective = {
  // 在绑定元素的 attribute 前
  // 或事件监听器应用前调用
  created(el, binding, vnode, prevVnode) {
    // 下面会介绍各个参数的细节
  },
  // 在元素被插入到 DOM 前调用
  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) {}
}
钩子参数

指令的钩子会传递以下几种参数:

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

简化形式

虽然钩子函数很多,但是可能有时候我们仅需要mountedupdated,其他的钩子不需要,这时候可以简写。

例如:

app.directive('color', (el, binding) => {
  // 这会在 `mounted` 和 `updated` 时都调用
  el.style.color = binding.value
})

对象字面量

如果指令需要多个值,可以直接传递一个JavaScript字面量。

<div v-demo="{ color: 'white', text: 'hello!' }"></div>
app.directive('demo', (el, binding) => {
  console.log(binding.value.color) // => "white"
  console.log(binding.value.text) // => "hello!"
})

组件上使用

在组件上使用时,指令会应用到组件的根节点元素,假如若有多个元素,并不是一个总元素包含所有的元素,则指令将不能使用并有提示。

相关文章:

  • wirehark数据分析与取证hack.pcapng
  • Netty — (二) 组件:EventLoop
  • Nested嵌套对象类型还挺实用
  • 这些js手写题你能回答上来几道
  • 微服务 高可用
  • TPH-yolov5 小目标检测
  • 光通信综合测试仪 光缆施工维护单位用的必要仪器--TFN HC2800
  • Putty 安装配置使用
  • Hydra复现记录(问题)
  • STM32第一课:STM硬件实物图+功能简介
  • 4. SQL语法中的一些基本概念
  • Unity注解使用方法快速上手
  • [网赚项目] 羊了个羊,周边日赚几百几千玩法
  • Appium PO模式UI自动化测试框架——设计与实践
  • Mybatis面试合集
  • 30天自制操作系统-2
  • HTTP请求重发
  • iOS仿今日头条、壁纸应用、筛选分类、三方微博、颜色填充等源码
  • Java 最常见的 200+ 面试题:面试必备
  • Java方法详解
  • nodejs调试方法
  • Python学习之路16-使用API
  • Spark VS Hadoop:两大大数据分析系统深度解读
  • windows-nginx-https-本地配置
  • 服务器从安装到部署全过程(二)
  • 更好理解的面向对象的Javascript 1 —— 动态类型和多态
  • 关于Flux,Vuex,Redux的思考
  • 每天一个设计模式之命令模式
  • 排序(1):冒泡排序
  • 前端存储 - localStorage
  • 算法-图和图算法
  • 项目管理碎碎念系列之一:干系人管理
  • 小白应该如何快速入门阿里云服务器,新手使用ECS的方法 ...
  • ​如何防止网络攻击?
  • #我与Java虚拟机的故事#连载18:JAVA成长之路
  • $.ajax()
  • (4)通过调用hadoop的java api实现本地文件上传到hadoop文件系统上
  • (C#)一个最简单的链表类
  • (delphi11最新学习资料) Object Pascal 学习笔记---第2章第五节(日期和时间)
  • (delphi11最新学习资料) Object Pascal 学习笔记---第8章第5节(封闭类和Final方法)
  • (windows2012共享文件夹和防火墙设置
  • (附源码)spring boot智能服药提醒app 毕业设计 102151
  • (一)UDP基本编程步骤
  • (一)使用Mybatis实现在student数据库中插入一个学生信息
  • (转)linux下的时间函数使用
  • (转)自己动手搭建Nginx+memcache+xdebug+php运行环境绿色版 For windows版
  • .NET 2.0中新增的一些TryGet,TryParse等方法
  • .NET 8 中引入新的 IHostedLifecycleService 接口 实现定时任务
  • .NET core 自定义过滤器 Filter 实现webapi RestFul 统一接口数据返回格式
  • .NET 中创建支持集合初始化器的类型
  • .Net6使用WebSocket与前端进行通信
  • .NET企业级应用架构设计系列之结尾篇
  • .NET上SQLite的连接
  • .NET下的多线程编程—1-线程机制概述
  • .project文件