Vue3逻辑复用及内置组件

 Vue3的逻辑复用主要通过“组合式函数”、“自定义指令”及“插件”来实现。提高了代码复用性,增强代码可维护性及促进团队合作。

1 逻辑复用

1.1 组合式函数

利用Vue组合式API来封装和复用有状态逻辑的函数。对组合式函数有如下约定:

  1. 命名,用驼峰法,并以use作开头。
  2. 输入参数,可以接收ref或getter类型的参数,最好用toValue()函数处理下这种类型的参数。
  3. 推荐始终返回一个包含多个ref的普通的非响应式对象。这样对该对象在组件中解构后仍可以保持响应性。
  4. 确保在onUnmounted()时清理副作用。
  5. 组合式函数只能在<script setup>或setup()钩子中被调用。也只能被同步调用。
import { ref, toValue, watchEffect} from "vue";
import type {Ref} from "vue"
export function useFetch(url: string | Ref<any> ) {const data = ref(null)const error = ref(null)const fetchFun = () => {data.value = nullerror.value = nullfetch(toValue(url)).then((res) => res.json()).then((json) => (data.value = json)).catch((err) => (error.value = err))}watchEffect(() => {fetchFun()})return { data, error }
}

1.2 自定义指令

重用涉及普通元素的底层DOM访问的逻辑。一个自定义指令由一个包含类似组件生命周期钩子的对象来定义。

el

指令所绑定的DOM元素。

binding对象

value: 传递给指令的值

oldValue: 之前的值

arg: 传递给指令的参数

modifiers:一个包含修饰符的对象

instance:使用该指令的组件实例

dir: 指令的定义对象

vnode

绑定元素的底层VNode

prevVnode

之前的渲染中指令所绑定元素的VNode,仅在beforeUpdate和updated钩子中使用。

表 钩子函数中的参数

<script setup lang="ts">
const vFocus = {mounted(el:HTMLElement,bindObj:{value: any,arg: string,modifiers:object}) {el.focus()console.log(bindObj)}
}
</script>

1.3 插件

能为Vue添加全局功能的工具代码。

一个插件可以是一个拥有install()方法的对象,也可以是install函数本身。它会接收app应用实例和传递给app.use的额外选项作为参数。

它有以下的作用:

  1. 通过app.component()和app.directive()注册一个或多个全局组件或自定义指令。
  2. 通过app.provice 使一个资源可被注入进整个应用。
  3. 向app.config.globalProperties中添加一些全局实例属性和方法。
  4. 一个可能包含上述三种功能的功能库。
//globalProvide.ts
export default {install(app:App,options: object) {console.log(app,options)app.provide("globalProvide",options)}
}// main.ts
app.use(globalProvide,{other: 'hmf',address: '深圳'})

2 内置组件

2.1 Transition

会在一个元素组件进入和离开DOM时应用动画。仅支持单个元素或组件作为其插槽内容。

触发条件:1)v-if、v-show触发。2)<component>切换的动态组件。3)改变元素的key属性。

图 6个应用于进入与离开过渡效果的CSS class

<Transition>有个name 属性,用于声明一个过渡效果名。例如,name设置为custom,则上面的v-enter-from 就变为custom-enter-from。

<script setup lang="ts">
import {ref} from "vue";const tag = ref(true)
const count = ref(0)
</script><template>
<button @click="tag = !tag">tag切换</button>
<button @click="count++">{{ count }}</button>
<div class="transition-container"><transition name="custom"><div v-if="tag">hello transition</div></transition><transition name="custom"><div v-if="tag" :key="count">hello {{ count }}</div></transition>
</div>
</template><style scoped>
.custom-enter-active,
.custom-leave-active {transition: opacity 0.5s ease;
}.custom-enter-from,
.custom-leave-to {opacity: 0;
}
</style>

2.2 TransitionGroup

会在一个v-for列表中的元素或组件被插入、移动或移除时应用动画。

  1. 默认情况下,它不会渲染一个容器元素,可以传入tag来指定容器元素。
  2. 列表中的每个元素都必须有独一无二的key。
  3. CSS过渡的class会被应用在列表内的元素上,而不是容器元素上。
<script setup lang="ts">
import {ref} from "vue";let count = 0
const array:Array<number> = []
const arr = ref(array)function randomOpera(type: number) {const pos = Math.floor(Math.random() * arr.value.length)if (type == -1) {if (arr.value.length === 0) returnarr.value.splice(pos,1)} else {arr.value.splice(pos,0,count)count++}
}
</script><template>
<div><button @click="randomOpera(1)">插入</button><button @click="randomOpera(-1)">删除</button>
</div>
<div><transition-group name="custom"><div v-for="item in arr" :key="item">{{ item }}</div></transition-group>
</div>
</template><style scoped>
.custom-enter-active,
.custom-leave-active {transition: opacity 0.5s ease;
}.custom-enter-from,
.custom-leave-to {opacity: 0;
}
</style>

2.3 KeepAlive

在多个组件间动态切换时缓存被移除的组件实例。

可以指定需要被包含/排除的组件,指定形式有:1)字符串。2)正则表达式。3)包含这两个的数组。

被缓存实例的生命周期为:onActivated和onDeactivated。

<script setup lang="ts">
import {ref} from "vue";
import ComponentA from "@/article/components/ComponentA.vue";
import ComponentB from "@/article/components/ComponentB.vue";const tag = ref(true)
</script><template>
<button @click="tag = !tag">tag切换</button>
<keep-alive exclude="ComponentB"><component :is="tag ? ComponentA : ComponentB"/>
</keep-alive>
</template>

2.4 Teleport

使得一个组件模版的一部分逻辑上从属于该组件,但其部分DOM可以被渲染到该组件之外的其他HTML节点。

<script setup lang="ts">
import {ref} from "vue";const tag = ref(false)
</script><template>
<div class="a6-container"><div><button @click="tag = !tag">切换tag</button></div><teleport to="body" v-if="tag"><div class="model">Hello Teleport</div></teleport>
</div>
</template><style scoped>
.model {background: rgba(229, 231, 231, 0.44);position: fixed;width: 50%;height: 50%;left: 25%;top: 25%;display: flex;justify-content: center;align-items: center;
}
</style>

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

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

相关文章

Sentinel限流规则详解

上一期教程讲解了 Sentinel 的快速入门&#xff1a;Sentinel快速入门&#xff0c;这一期主要讲述 Sentinel 的限流规则 簇点链路 簇点链路就是项目内的调用链路&#xff08;Controller -> Service -> Mapper&#xff09;&#xff0c;链路中被监控的每个接口就是一个资源…

wkhtmltopdf 工具安装与使用

前情提要&#xff1a; 最近一个同事请叫我一个问题&#xff0c;他发现一片不错的博文&#xff0c;是在博客园的&#xff0c;但是不能下载这篇文章&#xff0c;我看了一下才发现&#xff0c;原来csdn也是不行的。合理。毕竟是人家辛苦写的文章&#xff0c;不能就这么被别人随便c…

《Java初阶数据结构》----7.<优先级队列PriorityQueue>

前言 大家好&#xff0c;我目前在学习java。之前也学了一段时间&#xff0c;但是没有发布博客。时间过的真的很快。我会利用好这个暑假&#xff0c;来复习之前学过的内容&#xff0c;并整理好之前写过的博客进行发布。如果博客中有错误或者没有读懂的地方。热烈欢迎大家在评论区…

[渗透测试] 主动信息收集

主动信息收集 在红蓝对抗过程中&#xff0c;资产属于核心地位&#xff0c;攻击方&#xff08;红方&#xff09;要尽可能的去获取对方资产&#xff0c;暴露目标资产&#xff0c;包括IP地址、网络设备、安全设备、服务器、存储在服务器中的数据等。防守方也要清楚自己有多少有价…

宝塔SSL续签失败

我有2个网站a和b&#xff08;文字中用baidu.com替换我的域名&#xff09; b是要续签那个&#xff0c;但续签报错&#xff1a; nginx version: nginx/1.22.1 nginx: [emerg] host not found in upstream "github.com" in /www/server/panel/vhost/nginx/proxy/a.bai…

设计模式--创建型

实现 #include <iostream> #include <memory>// 抽象产品类 class Product {public:virtual ~Product() {}virtual void Operation() const 0; };// 具体产品 类A class ConcreteProductA : public Product {public:virtual void Operation() const override {st…

ESP-01S、ESP8266、ESP32等模块通信乱码的排查方法

ESP-01S、ESP8266、ESP32等模块通信乱码的排查方法 ESP-01S模块 遇到问题首先按重要顺序及排除法来解决问题 1&#xff0c;你的USB转串口工具是否有问题&#xff1f; 请将TXD与RXD短接在一起进行测试&#xff0c;自收自发应该是正常的&#xff0c;请确保这点。 ESP-01S的串口…

ffmpeg ffplay.c 源码分析二:数据读取线程

本章主要是分析 数据读取线程read_thread 中的工作。如上图红色框框的部分 从ffplay框架分析我们可以看到&#xff0c;ffplay有专⻔的线程read_thread()读取数据&#xff0c; 且在调⽤av_read_frame 读取数据包之前需要做&#xff1a; 1.例如打开⽂件&#xff0c; 2.查找配置解…

Servlet 3.0的新特征

版权声明 本文原创作者:谷哥的小弟作者博客地址:http://blog.csdn.net/lfdfhlServlet 3.0概述 Servlet 3.0规范是在2009年随着Java EE 6的发布而推出的。它引入了一系列新特性和改进,旨在简化Web应用的开发和部署过程,并提高Web应用的性能和可扩展性。Servlet 3.0的发布标…

大语言模型-对比学习-Contrastive Learning

一、对比学习概念 对比学习是一种特殊的无监督学习方法。 旨在通过拉近相关样本的距离并且推远不相关样本的距离&#xff0c;来学习数据表示。 通常使用一种高自由度、自定义的规则来生成正负样本。在模型预训练中有着广泛的应用。 二、对比学习小案例 对比学习主要分为三个…

02 MySQL数据库管理

目录 1.数据库的结构 sql语言主要由以下几部分组成 2. 数据库与表的创建和管理 1&#xff0c;创建数据库 2&#xff0c;创建表并添加数据 3&#xff0c;添加一条数据 4&#xff0c;查询数据 5&#xff0c;更新数据 6&#xff0c;删除数据 3.用户权限管理 1.创建用户 …

js轮播图制作

实现一个简单的JavaScript轮播图可以通过以下步骤完成&#xff1a; 创建HTML结构&#xff0c;包括轮播图容器和图片列表。 使用CSS进行样式设置&#xff0c;包括隐藏多余的图片。 使用JavaScript编写函数来控制图片的切换。

C#中栈和堆以及修饰符

关于堆中字符串的存放 string s1"123" string s2"123" string s1"456" 此时s1输出为456 而s2仍然为123 因为在使用 String str "字符串" 的方式来创建String变量的时候&#xff0c;那么String的值便会存储在String常量池中&#x…

Keepalived和Haproxy

Keepalived和Haproxy 一、Keepalived 1、keepalived概念 调度器的高可用 vip地址主备之间的切换&#xff0c;主在工作时&#xff0c;vip地址值在主上&#xff0c;主停止工作&#xff0c;vip飘移到备服务器 在主备的优先级不变的情况下&#xff0c;主恢复工作&#xff0c;v…

C++——编译报重复定义错误的解决办法

原因&#xff1a; 头文件被多次编译。 解决办法&#xff1a; 找到包含头文件的地方&#xff0c;仔细检查。 比如&#xff1a; 这两句话是包含关系&#xff0c;写了第一句就不用第二句了。 因为&#xff1a;第一句是编译 tracker/detector/rknn_model_zoo/examples/yolov5/c…

【MySQL进阶之路 | 高级篇】简谈redo日志

1. 前言 事务有四种特性&#xff1a;原子性&#xff0c;一致性&#xff0c;隔离性和持久性。那么事务的四种特性到底是基于什么机制实现呢&#xff1f; 事务的隔离性由锁机制实现。而事务的原子性&#xff0c;一致性和持久性由事务的redo日志和undo日志来保证。 REDO LOG称为…

云计算实训13——DNS域名解析、ntp时间服务器配置、主从DNS配置、多区域DNS搭建

一、DNS域名解析 1.正向解析 将域名解析为IP地址 DNS正向解析核心配置 (1)安装bind [rootdns ~]# yum -y install bind (2)编辑配置文件 编辑named.conf文件&#xff0c;限定访问权限 [rootdns ~]# vim /etc/named.conf 编辑named.rfc文件&#xff0c;指定要访问的域名 [ro…

【数据结构】:用Java实现链表

在 ArrayList 任意位置插入或者删除元素时&#xff0c;就需要将后序元素整体往前或者往后搬移&#xff0c;时间复杂度为 O(n)&#xff0c;效率比较低&#xff0c;因此 ArrayList 不适合做任意位置插入和删除比较多的场景。因此&#xff1a;java 集合中又引入了 LinkedList&…

一步一步测试DNS隧道

目录 0、前言 1、DNS解析 1.1 DNS简介 1.2 DNS查询类型 1.3 DNS解析过程 2、DNS隧道准备工作 2.1 DNS隧道介绍 2.1.1 什么是DNS隧道&#xff1f; 2.1.2 DNS隧道的原理 2.2 客户端、服务端准备 2.3 域名准备 2.4 连接隧道 2.5 遇坑 3、隧道确认和利用…

Windows本地启动Redis

找到本地redis目录 输入cmd,然后输入redis-server.exe redis.windows.conf&#xff0c;默认端口为6379 再新打开一个cmd&#xff0c;输入redis-cli.exe -p 6379 -a &#xff08;你在redis.windows.conf中设置的密码&#xff09;