Vue3学习记录(七)--- 组合式API之指令和插件

一、内置指令

1、v-memo

​ 该指令是Vue3的v3.2版本之后新增的指令,用于实现组件模板缓存,优化组件更新时的性能。该指令接收一个固定长度的依赖值数组,在组件进行更新渲染时,如果数组中的每个依赖值都与上一次渲染时的值相同,则指令所在的模板元素及其子元素的更新渲染将会被跳过,甚至在创建虚拟DOM的阶段也会跳过这些节点的创建。只有当依赖值发生变化时,指令所在的模板元素及其子元素才会进行更新渲染。

<template><div><div v-memo="[testA,testB]"><h4>验证v-memo指令的作用</h4></div></div>
</template><script setup>
import { ref } from 'vue'const testA = ref('testA')
const testB = ref('testB')
</script>

​ 如果v-memo指令接收的是一个空数组[],则其作用与v-once效果相同,仅在初始阶段渲染模板元素一次,在后续的更新渲染中,模板元素及其所有子元素将被当作静态内容并跳过更新渲染。

与v-for一起使用:

v-memo指令最常见的使用场景是与v-for渲染的长列表结合使用,例如:当组件的selected状态发生变化时,默认在更新创建虚拟DOM时会重复创建大量的的vnode,进行diff对比更新。当我们使用v-memo="[item.id === selected]"时,表示只有当前元素的selected状态发生变化时,才会更新当前元素,避免了大量无用vnode的创建。

<!-- [item.id === selected] 表示只有当前元素的selected状态发生变化时 才会更新当前元素 -->
<div v-for="item in list" :key="item.id" v-memo="[item.id === selected]"><p>ID: {{ item.id }} - selected: {{ item.id === selected }}</p><p>...more child nodes</p>
</div>
2、v-for和v-if

​ 在Vue2中v-forv-if不允许用在同一元素上,因为两者没有一个明确的优先级。在Vue3中虽然不推荐同时使用v-forv-if,但两者可以同时使用。

​ 当两者作用于同一元素时,v-if的优先级高,首先被执行,且v-if无法访问到v-for中的数据。因此还是建议将两者放在不同元素上使用:

<ul><!-- 此时会报错 因为 item 是v-for中的属性 v-if中无法访问 --><li v-for="item in list" v-if="item === 'aaa'">{{ item }}</li>
</ul><!-- 建议使用以下写法 --><ul><template v-for="item in list"><li  v-if="item === 'aaa'">{{ item }}</li></template>
</ul>
3、其余指令

​ 其余指令在Vue3中的功能与Vue2中功能相同,并未更新,此处就不展开讲述了。需要翻阅的可以查看我之前发布的内容:Vue2学习笔记。

二、自定义指令

1、基础用法

​ 除了Vue为我们提供的内置指令之外,还允许注册自定义指令,实现逻辑复用。但不建议过多使用自定义指令,只有当功能需要直接操作 DOM 时,才应该使用自定义指令。

​ 一个自定义指令由一个包含指令钩子函数的对象来定义。在 <script setup> 中,任何以 v 开头的驼峰式命名的变量都可以被用作一个自定义指令,例如:vFocus可以在模板中以v-focus指令的形式使用:

<template><div><!-- 在模板元素上使用自定义指令 --><input type="text" v-focus /></div>
</template><script setup lang="ts">
// 声明一个自定义指令 作用为控制元素自动获取焦点
const vFocus = {mounted: (el) => el.focus()
}
</script>

​ 在 <script setup> 中声明的自定义指令,只能在当前组件实例内使用。如果需要,也可以在mian.js中通过应用实例将自定义指令注册为全局指令,可在应用全局范围内使用:

// mian.js 文件
import { createApp } from 'vue'
import App from './App.vue'// 创建应用实例
const app = createApp(App)
// 声明一个自定义指令 作用为控制元素自动获取焦点
const vFocus = {mounted: (el) => el.focus()
}
// 注册全局的自定义指令
app.directive('focus', vFocus)
2、在组件上使用自定义指令

​ 当自定义指令应用在组件上时,如果子组件只有一个根节点,则指令会被透传到子组件的根节点上;如果子组件含有多个根节点,自定义指令将会被忽略,同时会抛出一个警告。而且自定义指令不能通过$attrs对象传递给某个元素。

​ 不建议在组件上使用自定义指令。

3、指令钩子函数

​ 一个自定义指令对象中的钩子函数有七个可选的钩子函数,分别为:created()beforeMount()mounted()beforeUpdate()updated()beforeUnmount()unmounted()

const myDirective = {// 该钩子函数在绑定元素属性或事件监听器应用之前被调用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) {}
}

​ 每个钩子函数都接收四个参数,其中除了参数el之外,其余元素都是只读的。

​ 参数el表示指令绑定的DOM元素,可用于直接进行DOM操作,例如:

mounted: (el) => el.focus()

​ 参数binding是一个对象,其中包含以下属性:

  • value:指令接收的属性值。
  • oldValue:元素更新之前指令接收的属性值,仅在beforeUpdate()updated()钩子函数中可用。
  • arg:指令后面跟随的参数,元素以v-指令:参数的形式设置参数。
  • modifiers:对象结构,对象中存储了指令的修饰符,以{修饰符名称: true}的形式存储。
  • instance:指令所在的组件实例。
  • dir:指令的定义对象。

​ 参数vnode表示绑定元素对应的虚拟DOM。

​ 参数prevNode表示元素更新前所对应的虚拟DOM,仅在beforeUpdate()updated()钩子函数中可用。

update()钩子函数为例:
<template><div><!-- 在模板元素上使用自定义指令 --><input type="text" v-focus:foo.aaa="'ccc'" /></div>
</template><script setup>
// 声明一个自定义指令 作用为控制元素自动获取焦点
const vFocus = {// 该钩子函数在绑定元素更新完成后调用updated(el, binding, vnode, prevVnode) {console.log('updated---el---',el);console.log('updated---binding---',binding);console.log('updated---vnode---',vnode);console.log('updated---prevVnode---',prevVnode);},
}
</script>

控制台输出结果:

在这里插入图片描述

4、简写形式

​ 如果一个自定义指令,只需要在mounted()updated()钩子函数中执行相同的代码,无需其他钩子函数参与,那么此时可以直接用一个函数来声明该自定义指令:

<template><div><!-- 在模板元素上使用自定义指令 --><p v-color="'red'">自定义指令简写</p></div>
</template><script setup lang="ts">
// 利用简写形式 声明一个自定义指令 作用为改变元素的字体颜色
const vColor = (el,binding) => {// 该函数会在 mounted 和 updated 时调用el.style.color = binding.value;
}
</script>
5、对象字面量属性值

​ 如果一个自定义指令需要接收多个属性值,则可以通过对象字面量的形式来传递属性值:

<template><div><p v-color="{ color: 'red', bgColor: 'green' }">自定义指令简写</p></div>
</template><script setup lang="ts">
// 利用简写形式 声明一个自定义指令 作用为改变元素的字体颜色
const vColor = (el,binding) => {el.style.color = binding.value.color;el.style.backgroundColor = binding.value.bgColor;
}
</script>

三、插件

1、简介

​ 插件(Plugins)是Vue中一种重要的扩展机制,允许开发者向 Vue 应用示例添加全局级别的功能。但插件本身并不具有添加全局功能的能力,而是需要借助app.component()等方法去实现功能。所以在我看来插件更像是一个将main.js中功能抽出集合成的模块,然后通过导入模块,实现相应的功能,避免在main.js文件中书写过多的逻辑代码。

​ 插件常见的应用场景主要包括:

  • 引用第三方库,例如vue-router、ElementPlus等等。
  • 结合app.component()注册全局组件。
  • 结合app.directive()注册全局自定义指令。
  • 结合app.provide()提供全局依赖。
  • 结合app.config.globalProperties添加全局属性或全局方法。
2、基本用法

​ 插件可以是一个拥有install()安装方法的对象,也可以直接是一个安装方法本身。插件的安装方法接收两个参数:一个app表示插件安装到的Vue应用实例对象,一个options表示插件安装时的可选配置项:

const myPlugin = {install(app, options) {// app 是插件要要安装的应用实例// options 是插件安装时的可选配置项}
}

​ 在安装插件时,只需要将插件所在js文件导入到mian.js中,然后通过app.use()方法进行安装即可:

import { createApp } from 'vue'
// 导入插件
import myPlugin from './plugins/myPlugin.js'
const app = createApp({})
// 安装插件
app.use(myPlugin, {/* 可选的选项 这里面的内容会传递给插件install()方法 的 options 参数 */
})
3、自定义插件
创建插件:

​ 首先创建一个插件的js文件,内部书写插件的具体功能逻辑代码:

// logPlugin.js
const LogPlugin = {// 插件的安装方法install(app, options) {// 通过 provide() 方法传递全局方法app.provide('log', function (message) {// 如果传入了options.prefix,则在打印message时加上前缀if (options && options.prefix) {console.log(`${options.prefix}: ${message}`);} else {// 否则直接打印messageconsole.log(message);}});}
}// 导出插件
export default LogPlugin;
安装插件:

​ 在main.js导入插件文件,并通过app.use()进行安装:

import { createApp } from 'vue'import App from './App.vue'
import LogPlugin from './plugins/logPlugin'// 创建应用实例
const app = createApp(App)
// 将插件安装到应用示例上
app.use(LogPlugin, { prefix: '小助手提示您' })
app.mount('#app')
使用插件:

​ 在组件中需要通过inject()接收插件提供的全局方法:

<script setup>
import { inject } from 'vue';const log = inject('log');log('使用自定义插件的方法')// 其他场景使用
</script>s

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

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

相关文章

【微服务】Nacos配置管理

&#x1f4dd;个人主页&#xff1a;五敷有你 &#x1f525;系列专栏&#xff1a;微服务 ⛺️稳中求进&#xff0c;晒太阳 Nacos除了可以做注册中心&#xff0c;同样可以做配置管理来使用。 1.统一配置管理 当微服务部署的实例越来越多&#xff0c;达到数十、数百时&am…

Java:接口

目录 1.接口的概念2.接口的语法规则3.接口使用4.接口的特性5.实现多个接口6.接口中的继承7.抽象类和接口的区别 1.接口的概念 在现实生活中&#xff0c;接口的例子比比皆是&#xff0c;比如&#xff1a;笔记本上的USB口&#xff0c;电源插座等。 电脑的USB口上&#xff0c;可以…

机器学习-可解释性机器学习:支持向量机与fastshap的可视化模型解析

一、引言 支持向量机(Support Vector Machine, SVM)作为一种经典的监督学习方法&#xff0c;在分类和回归问题中表现出色。其优点之一是生成的模型具有较好的泛化能力和可解释性&#xff0c;能够清晰地展示特征对于分类的重要性。 fastshap是一种用于快速计算SHAP值&#xff08…

做跨境用哪种代理IP比较好?怎么选到干净的IP?

代理IP对于做跨境的小伙伴来说&#xff0c;都是必不可少的工具&#xff0c;目前出海的玩法已经是多种多样&#xff0c;开店、账号注册、短视频运营、直播带货、网站SEO等等都是跨境人需要涉及到的业务。而国外代理IP的获取渠道非常多&#xff0c;那么做跨境到底应该用哪种代理I…

鸿蒙Harmony应用开发—ArkTS声明式开发(容器组件:RelativeContainer)

相对布局组件&#xff0c;用于复杂场景中元素对齐的布局。 说明&#xff1a; 该组件从API Version 9开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起始版本。 规则说明 容器内子组件区分水平方向&#xff0c;垂直方向&#xff1a; 水平方向为left&…

Python二级备考(1)考纲+基础操作

考试大纲如下&#xff1a; 基本要求 考试内容 考试方式 比较希望能直接刷题&#xff0c;因为不懂的比较多可能会看视频。 基础操作刷题&#xff1a; 知乎大头计算机1-13题 import jieba txtinput() lsjieba.lcut(txt) print("{:.1f}".format(len(txt)/len(ls)…

【QT入门】实现一个简单的图片查看软件

声明&#xff1a;该专栏为本人学习Qt知识点时候的笔记汇总&#xff0c;希望能给初学的朋友们一点帮助(加油&#xff01;) 往期回顾&#xff1a; 【QT入门】qmake和cmake的简单区别-CSDN博客 【QT入门】VS qt和QtCreator项目的相互转换-CSDN博客 【QT入门】Qt架构与三个窗口的区…

【leetcode】628.三个数的最大乘积

前言&#xff1a;剑指offer刷题系列 问题&#xff1a; 给你一个整型数组 nums &#xff0c;在数组中找出由三个数组成的最大乘积&#xff0c;并输出这个乘积。 示例&#xff1a; 输入&#xff1a;nums [1,2,3] 输出&#xff1a;6思路1&#xff1a; 先去计算输入列表 nums …

Flask vs. Django:选择适合你的Web开发框架【第134篇—Flask vs. Django】

&#x1f47d;发现宝藏 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。【点击进入巨牛的人工智能学习网站】。 Flask vs. Django&#xff1a;选择适合你的Web开发框架 在选择一个适合你项目的Web开发框架…

【数据库】数据库基本知识

1.数据库的四个基本概念 1.1 数据&#xff1a;描述事务的符号记录 1.2 数据库&#xff1a;概括的说&#xff0c;数据库数据具有永久存储、有组织的、可共享的大量数据的集合&#xff0c;数据库中的数据按一定的数据模型组织、描述和储存&#xff0c;具有较小的冗余度、较高的…

如何使用Net2FTP+cpolar搭建专属文件共享站点并实现无公网IP远程访问——“cpolar内网穿透”

文章目录 1.前言2. Net2FTP网站搭建2.1. Net2FTP下载和安装2.2. Net2FTP网页测试 3. cpolar内网穿透3.1.Cpolar云端设置3.2.Cpolar本地设置 4.公网访问测试5.结语 1.前言 文件传输可以说是互联网最主要的应用之一&#xff0c;特别是智能设备的大面积使用&#xff0c;无论是个人…

Java的类与对象

前言 Java是一门纯面向对象的语言(Object Oriented Program&#xff0c;简称OOP)&#xff0c;在面向对象的世界里&#xff0c;一切皆为对象。面向对象是解决问题的一种思想&#xff0c;主要依靠对象之间的交互完成一件事情。用面向对象的思想来涉及程序&#xff0c;更符合人们…

从单机到分布式微服务,大文件校验上传的通用解决方案

一、先说结论 本文将结合我的工作实战经历&#xff0c;总结和提炼一种从单体架构到分布式微服务都适用的一种文件上传和校验的通用解决方案&#xff0c;形成一个完整的方法论。本文主要解决手段包括多线程、设计模式、分而治之、MapReduce等&#xff0c;虽然文中使用的编程语言…

Spring6--IOC反转控制 / 基于XML管理bean

1. 容器IOC 先理解概念&#xff0c;再进行实际操作。概念比较偏术语化&#xff0c;第一次看可能看不懂&#xff0c;建议多看几遍&#xff0c;再尝试自己独立复述一遍&#xff0c;效果会好些 1.1. IOC容器 1.1.1. 控制反转&#xff08;IOC&#xff09; IOC (Inversion of Con…

【一起学Rust | 基础篇】rust线程与并发

文章目录 前言一、创建线程二、mpsc多生产者单消费者模型1.创建一个简单的模型2.分批发送数据3. 使用clone来产生多个生产者 三、共享状态&#xff1a;互斥锁1. 创建一个简单的锁2. 使用互斥锁解决引用问题 前言 并发编程&#xff08;Concurrent programming&#xff09;&#…

es 集群核心概念以及实践

节点概念&#xff1a; 节点是一个Elasticsearch的实例 本质上就是一个JAVA进程一台机器上可以运行多个Elasticsearch进程&#xff0c;但是生产环境一般建议一台机器上只运行一个Elasticsearch实例 每一个节点都有名字&#xff0c;通过配置文件配置&#xff0c;或者启动时候 -…

IBM:《CEO生成式 AI行动指南利用生成式 AI推动变革--所需了解的事项和所需采取的行动》

2024年2月IBM分享《CEO生成式 AI行动指南利用生成式 AI推动变革》报告。在该报告中&#xff0c;讨论了成功转型所必不可少的基本领导素质&#xff0c;并展示了如何将这些技能应用于培养 AI 赋能的人才、发展 AI 赋能的业务&#xff0c;以及利用 AI 赋能的数据与技术。 报告提到…

代码随想录算法训练营第十六天|104.二叉树的最大深度、559.n叉树的最大深度、111.二叉树的最小深度、222.完全二叉树的节点个数

代码随想录算法训练营第十六天|104.二叉树的最大深度、559.n叉树的最大深度、111.二叉树的最小深度、222.完全二叉树的节点个数 104.二叉树的最大深度 给定一个二叉树 root &#xff0c;返回其最大深度。 二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数…

QT UI窗口常见操作

MainWidget::MainWidget(QWidget *parent): QWidget(parent), ui(new Ui::MainWidget) {ui->setupUi(this);// 设置主窗口背景颜色QPalette plt;plt.setColor(QPalette::Window,QColor(180,220,130));this->setPalette(plt);// 禁止窗口最大化按钮setWindowFlags(windowF…

你要的个性化生信分析服务今天正式开启啦!定制你的专属解决方案!全程1v1答疑!

之前在 干货满满 | 给生信小白的入门小建议 | 掏心掏肺版 中有提到&#xff0c;如果小伙伴们真的想学好生信&#xff0c;那编程能力是必须要有的&#xff01;但是可能有些小伙伴们并没有那么多的时间从头开始学习编程&#xff0c;又或是希望有人指导或者协助完成生信分析工作&a…