【Vue3】自定义组件directiveapp.use()

历史小剧场

崇祯很勤政,崇祯并非王国之君,弘光很昏庸,弘光活该倒霉,几百年来,我们都这样认为。
但我们之所以一直这样认为,只是因为有人这样告诉我们。
之所以有人这样告诉我们,是因为他们希望我们这样认为。 ---- 《明朝那些事儿》

app.directive

作用:注册自定义指令

自定义指令

指令钩子函数
  • created: 在绑定元素的attribute前或事件监听器前调用;
  • beforeMount: 在元素插入到DOM前调用;
  • mounted: 在绑定元素的父组件及它自己的所有子节点都挂载完成后调用(常用)
  • beforeUpdate: 绑定元素的父组件更新前调用
  • updated: 在绑定元素的父组件及它自己的所有子节点都更新后调用(常用)
  • beforeUnmount: 绑定元素的父组件卸载前调用
  • unmounted: 绑定元素的父组件卸载后调用
钩子参数

案例

export default {mounted(el: any, binding: any, vnode: any, prevNode: any) {console.log("tab mounted", el, binding, vnode, prevNode)const { activeClass, curIndex } = binding.value;const buttonList = el.querySelectorAll("button");buttonList[curIndex].classList.add(activeClass);},updated(el: any, binding: any, vnode: any, prevNode: any) {console.log("tab updated", el, binding, vnode, prevNode)const buttonList = el.querySelectorAll("button");let { activeClass, curIndex } = binding.oldValue;buttonList[curIndex].classList.remove(activeClass);activeClass = binding.value.activeClass;curIndex = binding.value.curIndex;buttonList[curIndex].classList.add(activeClass);}
}
  1. el: 指定绑定到的元素。
    在这里插入图片描述
  2. binding: 对象,通常包含如下属性
    1. value: 传递给指令的值
    2. oldValue: 之前的值,仅在 beforeUpdate 和 updated 中可用
    3. arg: 传递给指令的参数
    4. modifers: 一个包含修饰符的对象
    5. instance: 使用该指令的组件实例
    6. dir: 指令的定义对象
      在这里插入图片描述
  3. vnode: 代表绑定元素的底层VNode
    在这里插入图片描述
  4. prevNode: 代表之前的渲染中指定所绑定元素的VNode。仅在 beforeUpdate 和 updated 钩子中可用
    在这里插入图片描述
使用

这里,我们封装一个自定义v-tab指令来处理按钮点击切换样式变幻问题

定义一个组件 TestDirective.vue

<!-- TestDirective.vue -->
<template><div><div class="tab" @click="handleClick($event)"v-tab="{  activeClass: 'active',curIndex}"><button data-index="0">按钮一</button><button data-index="1">按钮二</button><button data-index="2">按钮三</button></div></div>
</template><script lang="ts">
import { ref } from 'vue'
import { tab } from '../directives'export default {name: 'TestDirective',directives: {tab},setup() {const curIndex = ref<number>(0)const handleClick = (event: MouseEvent) => {const tar = event.target as HTMLElementconst className = tar.classNameif (Object.is(className, '')) {const index = parseInt(tar.dataset?.index ?? "")curIndex.value = index}}return {handleClick,curIndex}}
}
</script><style lang="scss" scoped>
.tab {.active {background-color: skyblue;border: 2px solid slategrey;color: white;}
}
</style>

在src下面创建directives文件夹来存放自定义指令

在这里插入图片描述
index.ts

import tab from './tab'export {tab
}

tab.ts

export default {mounted(el: any, binding: any, vnode: any, prevNode: any) {console.log("tab mounted", el, binding, vnode, prevNode)const { activeClass, curIndex } = binding.value;const buttonList = el.querySelectorAll("button");buttonList[curIndex].classList.add(activeClass);},updated(el: any, binding: any, vnode: any, prevNode: any) {console.log("tab updated", el, binding, vnode, prevNode)const buttonList = el.querySelectorAll("button");let { activeClass, curIndex } = binding.oldValue;buttonList[curIndex].classList.remove(activeClass);activeClass = binding.value.activeClass;curIndex = binding.value.curIndex;buttonList[curIndex].classList.add(activeClass);}
}

运行之后,我们可以鼠标点击按钮切换样式
在这里插入图片描述

app.use

安装插件。 必须带一个install()方法

封装插件

这里,我们自己封装一个MyUI插件,且在插件里有两个自定义组件:MyButton 和 MyInput

在这里插入图片描述
MyButton.vue

<!-- MyButton.vue -->
<template><div><button class="my-button"><slot></slot></button></div>
</template><script lang="ts">
export default {name: 'MyButton',
}
</script><style lang="scss" scoped>.my-button {background-color: #41b883;color: #fff;border: none;border-radius: 10px;width: 80px;}
</style>

MyInput.vue

<!--  -->
<template><div><input class="my-input" type="text" placeholder="placeholderText" /></div>
</template><script lang="ts">
export default {name: 'MyInput',props: {placeholderText: {type: String,default: 'This is my input'}}
}
</script><style lang="scss" scoped>.my-input {width: 180px;border: 1px solid #ccc;border-radius: 4px;padding: 4px;}
</style>

index.ts

import MyButton from './MyButton.vue'
import MyInput from './MyInput.vue'const componentsPool: Map<String, any> = new Map()
componentsPool.set(MyButton?.name ?? "", MyButton)
componentsPool.set(MyInput?.name ?? "", MyInput)export default {install(app: any, options: any) {console.log("options => ", options)console.log("componentsPool => ", componentsPool)if (options?.components.length > 0) {// 按需加载options.components.map((com: String) => {componentsPool.has(com) && app.component(com, componentsPool.get(com))})} else {// 全部加载for (let [name, com] of componentsPool.entries()) {app.component(name, com)}}}
}

注意:在插件加载逻辑中,我们实现了按需加载。就是,如果我们在app.use()方法的第二个参数中传入components数组且长度大于0就进行按需加载,优化性能,否则的话,全部加载。

注册

我们在程序入口文件main.ts中进行注册

import MyUI from './libs/MyUI'
app.use(MyUI, {components: ['MyButton', 'MyInput']
})
使用

然后,我们创建一个TestUse.vue

<!--  -->
<template><div><my-button>测试按钮</my-button><my-input></my-input></div>
</template><script lang="ts">
export default {name: "TestUse",
}
</script><style lang="scss" scoped></style>

按照上面我们运行结果则是两个都可以展示
在这里插入图片描述
如果,我们在注册的时候只加载按钮

app.use(MyUI, {components: ['MyButton']
})

则只展示按钮
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/20240.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

比较与深浅克隆

1.比较 &#xff08;1&#xff09;Comparable接口&#xff1a;&#xff08;重写compareTo方法&#xff09; 由于它是一个接口&#xff0c;而且在这个接口中只有一个compareTo方法&#xff0c;所以所有实现该接口的类都需要重写。这个compareTo方法相当于制定一个比较标准&…

pyinstaller将py文件打包成exe

pyinstaller将py文件打包成exe 一、为什么需要将python文件打包成exe文件?二、具体操作步骤一、为什么需要将python文件打包成exe文件? python文件需要在python环境中运行,也就是需要安装python解释器。有时我们自己写的python程序需要分享给自己的朋友、同事或者合作伙伴,…

封装一个websocket,支持断网重连、心跳检测,拿来开箱即用

封装一个websocket&#xff0c;支持断网重连、心跳检测 代码封装 编写 WebSocketClient.js import { EventDispatcher } from ./dispatcherexport class WebSocketClient extends EventDispatcher {constructor(url) {console.log(url, urlurl)super()this.url url}// #soc…

STM32_FSMC_HAL(介绍)

FSMC&#xff08;Flexible Static Memory Controller&#xff09;是STM32微控制器中的一种内存控制器&#xff0c;它允许微控制器与外部存储器接口&#xff0c;如SRAM、NOR Flash、NAND Flash和PSRAM等。FSMC特别适用于需要高速数据交换和大量数据存储的应用场景。 典型应用&a…

react跨组件通信Context

案例&#xff1a;现在有个父-子-孙组件 需要进行组件通信 import { useState } from "react"; // 创建上下文 const CountContext React.createContext();//子组件 const SonComponent (props) > {return (<div><h2>子组件</h2><Grandson…

【机器学习】让大模型变得更聪明

文章目录 前言1. 理解大模型的局限性1.1 理解力的挑战1.2 泛化能力的挑战1.3 适应性的挑战 2. 算法创新&#xff1a;提高模型学习和推理能力2.1 自监督学习2.2 强化学习2.3 联邦学习 3. 数据质量与多样性&#xff1a;增强模型的泛化能力3.1 高质量数据的获取3.2 数据多样性的重…

#1 深度优先搜索

深搜思想 DFS其实是针对图论的一种搜索算法&#xff0c;由一个节点出发&#xff0c;不撞南墙不回头式的遍历所有的节点。 如先遍历1&#xff0c;沿&#xff08;1,2&#xff09;遍历2&#xff0c;再沿&#xff08;2,4&#xff09;遍历4&#xff0c;撞南墙&#xff08;边界条件…

XSS另类攻击(四)kali系统beef-xss安装和使用

★★免责声明★★ 文章中涉及的程序(方法)可能带有攻击性&#xff0c;仅供安全研究与学习之用&#xff0c;读者将信息做其他用途&#xff0c;由Ta承担全部法律及连带责任&#xff0c;文章作者不承担任何法律及连带责任。 1、环境说明 kali系统&#xff0c;ip&#xff1a;192.1…

k8s的ci/cd实践之旅

书接上回k8s集群搭建完毕&#xff0c;来使用它强大的扩缩容能力帮我们进行应用的持续集成和持续部署&#xff0c;整体的机器规划如下&#xff1a; 1.192.168.8.156 搭建gitlab私服 docker pull gitlab/gitlab-ce:latest docker run --detach --hostname 192.168.8.156 --publ…

SAP 生产订单批量报工(代码分享)

最近公司一直在对成本这块的业务进行梳理,影响比较大的就是生产这块的报工,经常会要求要批量的冲销报工,然后在继续报工,来调整生产订单的实际工时,前面的博客中已经给大家分享了批量冲销生产订单的代码, 下面给大家分享一下生产订单批量报工的代码 首先流程制造和离散制…

【算法】过桥

✨题目链接&#xff1a; 过桥 ✨题目描述 ✨输入描述: 第一行一个数n(2≤n≤2000) 接下来一行n个数a[i](1≤|a[i]|≤2000)表示浮块上的数字 ✨输出描述: 输出一行&#xff0c;表示对应的答案 ✨示例1 &#x1f4cd;输入 4 2 2 -1 2 &#x1f4cd;输出 2 &#x1f4cd;说明 1…

HNCTF 2024 ez_pecp 冰蝎+CS流量分析

考点:冰蝎webshell流量分析CS4.x流量解密 给了两个 流量包 第一个 ctf1.pcapng 查看其HTTP请求 而在CS中流量特征是基于tls协议 http-beacon 通信中&#xff0c;默认使用 GET 方法向 /dpixel 、/__utm.gif 、/pixel.gif 等地址发起请求&#xff0c;而且下发指令的时候会请求 …

如何使用浔川AI翻译机?——浔川AI社

1 前言 对于“如何使用浔川AI翻译机&#xff1f;”这个问题&#xff0c;我们官方 总结出以下结论&#xff1a; 首先&#xff1a; 复制以下代码&#xff1a; # -*- coding: utf-8 -*- import tkinter as tk import tkinter.messagebox import pickle import random# 窗口 wi…

Jmeter压测中遇到的问题汇总

Jmeter使用过程问题总结 一、某个请求的请求体中有中文字段&#xff0c;执行后该请求无法成功 解决方法&#xff1a;在取样器的内容编码处加上UTF-8 二、遇到接口请求后报401&#xff0c;请求未授权&#xff08;或者信息头管理器只写了cookie请求不成功&#xff09; 解决方…

记录深度学习GPU配置,下载CUDA与cuDnn,安装tensorflow

目标下载: cuda 11.0.1_451.22 win10.exe cudnn-11.0-windows-x64-v8.0.2.39.zip Anaconda的安装请看别的博主的,这里不再赘述 看看自己电脑的cuda 方法一:打开英伟达面板查看 方法二:使用命令行 随便找个文件夹,在顶部路径输入"cmd" 输入下面命令 nvidia-smi 我…

小程序配置自定义tabBar及异形tabBar配置操作

什么是tabBar&#xff1f; 小程序的tabbar是指小程序底部的一组固定导航按钮&#xff0c;通常包含2-5个按钮&#xff0c;用于快速切换小程序的不同页面。每个按钮都有一个图标和文本标签&#xff0c;点击按钮可以切换到对应的页面。tabbar通常放置在小程序的底部&#xff0c;以…

开发一套家政上门预约服务系统需要运用的关键技术

家政上门预约服务系统开发是指建立一个在线平台或应用程序&#xff0c;用于提供家政服务的预约和管理功能。该系统的目标是让用户能够方便地预约各种家政服务&#xff0c;如保洁、家庭护理、月嫂、家电维修等&#xff0c;并实现服务供应商管理和订单管理等功能。 开发一套家政上…

01Linux以及操作系统概述

课程目标 1.了解现代操作系统的整体构成及发展历史 2.了解Linux操作系统及其分支版本 3.直观上理解服务器端与桌面端版本的区别 课程实验 1.通过对CentOS和Ubuntu的演示&#xff0c;直观理解Linux与Windows的异同 课堂引入 本章内容主要为大家详细讲解Linux操作系统(以下简…

PPT 隐藏开启对象图层

目录预览 一、问题描述二、解决方案三、参考链接 一、问题描述 制作PPT的时候&#xff0c;有时候需要在一张PPT放置多个依次出现的内容&#xff0c;然后设置对应的动画&#xff0c;要是需要对某个内容进行修改的话&#xff0c;就会很不方便&#xff0c;这个时候就需要使用&…

基于SpringBoot的旅游攻略信息系统的设计与实现

文档介绍 用户群体 针对已经学习过SpringBoot的同学,希望通过一个项目来加强对框架的应用能力,增加项目经验 针对需要完成大学期间的毕设项目的同学,可以通过此文档了解整个系统技术架构,为自己的毕设论文提供指导性建议 文档内容 此文档内容可以让学习此实战项目的同学有一…