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

Vue3从零开始——如何巧妙使用setup语法糖、computed函数和watch函数

文章目录

  • 一、setup语法糖
  • 二、computed函数
    • 2.1 computed的基本用法
    • 2.2 computed vs methods
    • 2.3 注意事项
  • 三、watch函数
    • 3.1 watch的基本用法
    • 3.2 immediate和deep选项
  • 四、综合小Demo
  • 五、总结

在这里插入图片描述

下载 (14)

一、setup语法糖

之前我们在编写代码时每次都要编写setup()​ ,默认导出配置,还要返回变量和方法,有什么方法可以只写变量和方法,自动返回变量和方法?setup语法糖就可以帮助我们轻松解决这个麻烦。

下面为原本的代码:

<script>  
export default {setup() {// 创建一个响应式对象const state = reactive({count: 0,title: '计数器应用',});// 增加计数function increment() {state.count++;}// 重置计数function reset() {state.count = 0;}// 暴露定义的数据和函数return {state,increment,reset,};},};
</script>

使用setup​语法糖后:

<script setup>
import { reactive } from 'vue';
// 创建一个响应式对象
const state = reactive({count: 0,title: '计数器应用',
});// 增加计数
function increment() {state.count++;
}// 重置计数
function reset() {state.count = 0;
}</script>

观察可以发现我们去除掉了export defaultsetup函数和其中的返回语句,而我们仅仅是在 script 标签上添加了setup就实现了同样的功能,可以看到代码变得更加简洁,并且不用再写返回内容了。

二、computed函数

computed​ 函数用于定义计算属性,它基于其他响应式状态自动计算其值,并且具有缓存机制,只有在依赖项变化时才会重新计算。

2.1 computed的基本用法

setup​ 中,使用 computed​ 创建计算属性。

使用步骤:

  1. 导入computed​函数
  2. computed​函数中传入一个getter​函数用来计算数据
  3. 函数返回计算好的数据,返回值为一个计算属性 ref
<template><p>是否有出版书籍:</p><span>{{ publishedBooksMessage }}</span>
</template><script setup>
// 1. 导入 computed 函数
import { reactive, computed } from 'vue'const author = reactive({name: 'John Doe',books: ['Vue 2 - Advanced Guide','Vue 3 - Basic Guide','Vue 4 - The Mystery']
})// 2. 传入getter函数计算数据,返回的计算属性 publishedBooksMessage
const publishedBooksMessage = computed(() => {return author.books.length > 0 ? 'Yes' : 'No'
})
</script>

image

2.2 computed vs methods

与直接使用方法生成数据不同,computed​ 属性会缓存其结果,除非其依赖的响应式数据发生变化,否则不会重新计算。这对于性能优化非常重要。

前面代码的判断书籍数量是否大于0当然也可以使用函数来实现:

<template><p>是否有出版书籍:</p><p>{{ calculateBooksMessage() }}</p>
</template><script setup>
...// 通过函数实现
function calculateBooksMessage() {return author.books.length > 0 ? 'Yes' : 'No'
}
</script>

两种方式在结果上确实是完全相同的,然而,不同之处在于使用computed会基于其响应式依赖被缓存。计算属性publishedBooksMessage​仅会在其响应式依赖更新时才重新计算。这意味着只要 author.books​ 不改变,无论多少次访问 publishedBooksMessage​ 都会立即返回先前的计算结果,而不用重复执行 getter 函数。相比之下,方法调用总是会在重渲染发生时再次执行函数。

2.3 注意事项

  1. 避免直接修改计算属性值

由于从计算属性返回的值是一个“临时数据”,每当源状态发生变化时,就会创建一个新的数据。更改计算属性是没有意义的,因此计算属性的返回值应该被视为只读的,并且永远不应该被更改——应该更新它所依赖的源状态以触发新的计算。

  1. Getter 不应有副作用

计算属性的 getter 应只做计算而没有任何其他的副作用,这一点非常重要。举例来说,不要改变其他状态、在 getter 中做异步请求或者更改 DOM!一个计算属性的声明中描述的是如何根据其他值派生一个值。因此 getter 的职责应该仅为计算和返回该值。

比如说下面的代码:在 computed​ 中引入了副作用

import { ref, computed } from 'vue';const counter = ref(0);
const thresholdReached = ref(false);// 错误:在 computed getter 中引入副作用
const checkThreshold = computed(() => {if (counter.value > 10) {thresholdReached.value = true; // 副作用:修改了外部状态}return counter.value;
});

在这个例子中,checkThreshold​ 是一个 computed​ 计算属性,但它在 getter​ 中修改了 thresholdReached​ 变量。这是一个副作用,违反了 computed​ 的最佳实践原则。解决这个问题的方法是使用侦听器watch​函数来根据其他响应式状态的变更来创建副作用。

import { ref, computed, watch } from 'vue';const counter = ref(0);
const thresholdReached = ref(false);// 正确:纯粹的计算属性
const checkThreshold = computed(() => {return counter.value;
});// 使用 watch 监听 counter 的变化并执行副作用
watch(counter, (newVal) => {if (newVal > 10) {thresholdReached.value = true; // 副作用:修改外部状态}
});

三、watch函数

watch​ 函数用于监听响应式数据的变化,并执行副作用操作(如异步请求、手动修改DOM等)。在某些场景下,watch​ 比 computed​ 更适合处理复杂的副作用。

3.1 watch的基本用法

watch​ 允许我们在数据变化时执行某些操作,例如在用户输入时进行验证或发送请求。

使用步骤:

  1. 导入 watch​ 函数:从 vue​ 中导入 watch​ 函数。

  2. 定义响应式数据:使用 ref​ 或 reactive​ 定义你想要监听的响应式数据。

  3. 调用 watch​ 函数:传入要监听的响应式数据或计算属性,以及一个回调函数。当数据变化时,回调函数会被触发。

<template><div><input v-model="message" placeholder="输入一些内容"><p>输入内容:{{ message }}</p></div>
</template><script setup>
// 1. 导入 watch 函数
import { ref, watch } from 'vue';// 2. 定义响应式数据
const message = ref('');// 3. 监听 message 的变化,传入回调函数
watch(message, (newValue, oldValue) => {console.log(`message changed from ${oldValue} to ${newValue}`);
});
</script>

代码分析:

模板部分的input​使用 v-model​ 实现双向绑定 message​,实时更新输入框的值。

当输入框的内容改变时,message​相应的也会改变,此时watch​函数监听到message​变化后也会相应的执行回调函数来输出log信息。

image

3.2 immediate和deep选项

watch​ 函数接受一个可选的第三个参数,可以用来配置监听的行为:

  • immediate​:是否立即执行回调,默认是 false​。如果为 true​,则在监听开始后立即执行一次回调。
  • deep​:是否深度监听对象内部的变化,默认是 false​。如果为 true​,则会深度监听对象及其嵌套属性的变化。
<script setup>
import { ref, watch } from 'vue';const nestedObject = ref({ nested: { value: 1 } });// 深度监听对象
watch(nestedObject, (newVal, oldVal) => {console.log('嵌套对象已更改:', newVal);
}, { deep: true });</script>

四、综合小Demo

下面是一个结合了 setupcomputedwatch 的小Demo,在我们之前写的计数器的基础上实现以下功能:

  • 计数状态显示:根据当前计数值显示 “计数大于10” 或 “计数不大于10”。
  • 超限提示:当计数值超过 10 时,弹出提示框提醒用户 “计数已超过10!”。
<template><div><h1>{{ title }}</h1><p>当前计数:{{ count }}</p><p>计数状态:{{ countStatus }}</p><button @click="increment">增加</button><button @click="reset">重置</button></div>
</template><script setup>
import { ref, computed, watch } from 'vue';const title = ref('计数器');
const count = ref(0);// 使用 computed 创建一个计算属性
const countStatus = computed(() => {return count.value > 10 ? '计数大于10' : '计数不大于10';
});// 监听 count 的变化
watch(count, (newVal) => {if (newVal > 10) {alert('计数已超过10!');}
});function increment() {count.value++;
}function reset() {count.value = 0;
}</script><style scoped>
button {margin: 5px;padding: 10px 20px;background-color: #4caf50;color: white;border: none;border-radius: 5px;cursor: pointer;
}button:hover {background-color: #45a049;
}p {font-size: 18px;
}
</style>

代码分析:

  • ref setup​:在 setup​ 函数中使用 ref​ 创建了 title​ 和 count​ 两个响应式变量。
  • computed​:通过 computed​ 创建了 countStatus​ 计算属性,用于动态显示计数的状态。
  • watch​:使用 watch​ 监听 count​ 变量,当其值大于10时,弹出提示框。

image

五、总结

setup​ 语法糖、computed​ 函数和 watch​ 函数是 Vue 3 组合式 API 的核心特性,提供了更灵活和高效的方式来组织组件逻辑。本文我们详细讲解了setup​ 语法糖、computed​ 函数和 watch​ 函数的基本使用语法和注意事项,通过合理使用这些特性,可以大大提升代码的可读性和可维护性。希望本文的内容对大家有所帮助☺️。


参考文章:

Vue官网

在这里插入图片描述

相关文章:

Vue3从零开始——如何巧妙使用setup语法糖、computed函数和watch函数

文章目录 一、setup语法糖二、computed函数2.1 computed的基本用法2.2 computed vs methods2.3 注意事项 三、watch函数3.1 watch的基本用法3.2 immediate和deep选项 四、综合小Demo五、总结 一、setup语法糖 之前我们在编写代码时每次都要编写setup()​ ,默认导出配置&#x…...

【C++】 特殊类设计:从构思到实现,引领设计新潮流

&#x1f308; 个人主页&#xff1a;Zfox_ &#x1f525; 系列专栏&#xff1a;C从入门到精通 目录 &#x1f680; 前言 一&#xff1a; &#x1f525; 不能被拷贝的类 二&#xff1a; &#x1f525; 只能在堆上创建对象的类 三&#xff1a; &#x1f525; 只能在栈上创建对象的…...

性能调优 18. Tomcat整体架构及其设计精髓分析

1. Tomcat介绍 1.1. 介绍 ‌‌‌  这边使用的是Tomcat9来做说明&#xff0c;本章节先对Tomcat架构和设计有个整体认识。后续章节会对Tomcat性能调优做说明。 ‌‌‌  官方文档介绍 ‌‌‌  https://tomcat.apache.org/tomcat-9.0-doc/index.html1.2. Tomcat概念 ‌‌…...

【C++高阶】:特殊类设计和四种类型转换

✨ 人生如梦&#xff0c;朝露夕花&#xff0c;宛若泡影 &#x1f30f; &#x1f4c3;个人主页&#xff1a;island1314 &#x1f525;个人专栏&#xff1a;C学习 ⛺️ 欢迎关注&#xff1a;&#x1f44d;点赞 &#x1f442;&am…...

kafka基础概念二

1.Kafka中主题和分区的概念 1.主题Topic 主题-topic在kafka中是一个逻辑的概念&#xff0c;kafka通过topic将消息进行分类。不同的topic会被订阅该topic的消费者消费 但是有一个问题&#xff0c;如果说这个topic中的消息非常非常多&#xff0c;多到需要几T来存&#xff0c;因…...

牛客-热身小游戏

题目链接&#xff1a;热身小游戏 第一种写法&#xff1a;线段树 介绍第二种写法&#xff1a;并查集 对于一些已经查询过的点&#xff0c;我们可以往后跳&#xff0c;进行路径压缩&#xff0c;他们的父亲为下一个点。 a数组记录[ l , r ] 之间的乘积&#xff0c;初始值为1。…...

Python 深度学习调试问题

Python–深度学习解决的常见问题 1.在自己写测试样例的时候&#xff0c;有时候可能将要传入的是input_size&#xff0c;不小心传入为input_dim&#xff0c;这个时候会导致出现问题&#xff0c;自定义的卷积模块或者池化等模块会提示类型问题。 解决的策略是: 1.进行assert i…...

linux恶意请求

nginx访问日志&#xff1a; 162.243.135.29 - - [05/Jan/2024:00:12:07 0800] "GET /autodiscover/autodiscover.json?zdi/Powershell HTTP/1.1" 404 153 "-" "Mozilla/5.0 zgrab/0.x"107.151.182.54 - - [04/Mar/2024:11:30:06 0800] "G…...

Java 反射笔记总结(油管)

Java系列文章目录 IDEA使用指南 Java泛型总结&#xff08;快速上手详解&#xff09; Java Lambda表达式总结&#xff08;快速上手详解&#xff09; Java Optional容器总结&#xff08;快速上手图解&#xff09; Java 自定义注解笔记总结&#xff08;油管&#xff09; Jav…...

HTML表格、表单、标签、CSS、选择器

目录 一、HTML表格 二、表单 三、布局标签 四、CSS 五、选择器 一、HTML表格 table:表格 tr&#xff1a;行 td&#xff1a;单元格&#xff1b;rowspan:纵向合并相邻单元格&#xff1b;clospan&#xff1a;横向合并相邻单元格 th&#xff1a;单元格加粗居中 border&…...

【javaWeb技术】·外卖点餐小程序(脚手架学习1·数据库)

&#x1f308; 个人主页&#xff1a;十二月的猫-CSDN博客 &#x1f525; 系列专栏&#xff1a; &#x1f3c0;系统学javaWeb开发_十二月的猫的博客-CSDN博客 &#x1f4aa;&#x1f3fb; 十二月的寒冬阻挡不了春天的脚步&#xff0c;十二点的黑夜遮蔽不住黎明的曙光 【免费】项…...

LVS 实现四层负载均衡项目实战--DR模式

一、环境准备 主机名IP地址router eth0&#xff1a;172.25.254.100 eth1&#xff1a;192.168.0.100 clienteth0&#xff1a;172.25.254.200lvseth1&#xff1a;192.168.0.50web1web2 1、client配置 [rootclient ~]# cat /etc/NetworkManager/system-connections/eth0.nmconne…...

Python与Qt的对应版本

Python与Qt的对应版本并没有严格的一一对应关系&#xff0c;但通常在使用Python与Qt进行开发时&#xff0c;会选择一个兼容性较好的版本组合。Qt的Python绑定库主要是PyQt和PySide&#xff0c;以下是几个常见的搭配&#xff1a; 1. **PyQt5**&#xff1a; - Python 3.5及以上版…...

WPF篇(12)-Image图像控件+GroupBox标题容器控件

Image图像控件 Image也算是独门独户的控件&#xff0c;因为它是直接继承于FrameworkElement基类。 Image控件就是图像显示控件。Image类能够加载显示的图片格式有.bmp、.gif、.ico、.jpg、.png、.wdp 和 .tiff。要注意的是&#xff0c;加载.gif动画图片时&#xff0c;仅显示第…...

LeetCode 热题 HOT 100 (024/100)【宇宙最简单版】

【哈希表】No. 0128 最长连续序列【中等】&#x1f449;力扣对应题目指路 希望对你有帮助呀&#xff01;&#xff01;&#x1f49c;&#x1f49c; 如有更好理解的思路&#xff0c;欢迎大家留言补充 ~ 一起加油叭 &#x1f4a6; 欢迎关注、订阅专栏 【力扣详解】谢谢你的支持&am…...

如何在AWS上进行 环境迁移

在 AWS 上进行环境迁移通常包括以下几个步骤和最佳实践: 1. 评估和规划 评估当前环境:审查现有的应用程序、数据库、网络架构和依赖关系。确定迁移目标:明确迁移的目标(如成本节约、性能提升、可扩展性等)。选择迁移策略:根据应用程序的类型和复杂性,选择合适的迁移策略…...

云服务器和物理服务器的优缺点对比

云服务器优点在于灵活性强、成本效益高、易于扩展且支持全球化部署&#xff1b;缺点则包括安全性与可控性相对较弱&#xff0c;性能可能受限&#xff0c;以及存在服务中断风险。物理服务器则以其高性能、高稳定性、强安全性和完全可控性著称&#xff0c;但成本较高、扩展性受限…...

postgreSQL16添加审计功能

下载审计插件 https://github.com/pgaudit/pgaudit/releases他的分支版本支持不同的PGSQL按需下载 编译安装审计插件 tar -xvf pgaudit-16.0.tar.gzmake install USE_PGXS1 PG_CONFIG/app/postgresql/bin/pg_config启用postgreSQL审计功能 修改配置文件# 启用 pgAudit shar…...

如何应用OceanBase 的实时SQL诊断,解决AP场景下的痛点

随着数据量的快速增长与用户需求的变化&#xff0c;数据库的管理与优化工作日益凸显其重要性。作为DBA及开发者&#xff0c;您是否曾面临以下挑战&#xff1a; ○ 分析场景下&#xff0c;在处理大规模数据的且耗时较长的查询是&#xff0c;常涉及海量数据的处理及复杂的计算&…...

【数据结构】—— 栈

一、栈的基本概念1、栈的定义2、栈的常见基本操作 二、栈的顺序存储1、栈的顺序存储结构2、顺序栈存储实现&#xff08;1&#xff09;初始化&#xff08;2&#xff09;判空&#xff08;3&#xff09;进栈&#xff08;4&#xff09;出栈&#xff08;5&#xff09;取栈顶元素&…...

Kafka服务端日志详解

文章目录 服务端日志Topic消息存储方式主体介绍log文件追加记录消息index和timeindex索引文件 日志文件清理Kafka的文件高效读写机制Kafka的文件结构顺序写磁盘零拷贝 合理配置刷盘频率客户端消费进度管理 服务端日志 Kafka的日志信息是通过conf/server.properties文件中的log…...

C++ 数据语义学——进程内存空间布局

进程内存空间布局 1. 栈&#xff08;堆栈/栈区&#xff09;2. 堆&#xff08;堆区&#xff09;3. BSS段4. 数据段5. 代码段进程内存空间布局示意图可执行文件的内存布局示例代码 当把一个可执行文件加载到内存后&#xff0c;就变成了一个进程。这个虚拟空间&#xff08;内存&am…...

【数据结构】六、图:2.邻接矩阵、邻接表(有向图、无向图、带权图)

二、存储结构 文章目录 二、存储结构❗1.邻接矩阵1.1无向图❗邻接矩阵-无向图代码-C 1.2有向图❗邻接矩阵-有向图代码-C 1.3带权图1.4性能分析1.5相乘 ❗2.邻接表2.1无向图2.2有向图❗邻接表-C 邻接矩阵VS邻接表邻接矩阵邻接表 ❗1.邻接矩阵 图的邻接矩阵(Adjacency Matrix) 存…...

财务会计与管理会计(三)

文章目录 销售回款提成表MATCH函数的模糊查询在提成类业务中的应用 营业收入分类数据分析OFFSET函数在制作图表数据中的应用 自动生成销售记录对账单VLOOKUP函数的应用 销售回款提成表 MATCH函数的模糊查询在提成类业务中的应用 G3INDEX(I$1:M$1,MATCH(E3,H3:M3,1)) G3INDEX(…...

【数据结构和算法】(基础篇三)——栈和队列

栈和队列 栈&#xff08;Stack&#xff09;和队列&#xff08;Queue&#xff09;是两种非常基本的数据结构&#xff0c;它们主要用于存储和检索元素。尽管它们都用于管理一组数据项&#xff0c;但它们的访问规则和数组都是不同的。 栈 栈是一种后进先出&#xff08;Last In,…...

Linux截图工具gsnap移植arm平台过程记录

Linux截图工具gsnap移植arm平台过程记录 最近工作中一款新产品开发接近尾声&#xff0c;需要写文档截图产品图形&#xff0c;找了一款开源的Linux截屏工具gsnap&#xff0c;将其移植到ARM产品中&#xff0c;这里记录一下移植过程。 gsnap 这个工具源代码就是一个C语言源文件&a…...

密码学知识点02

#来自ウルトラマンレオ&#xff08;雷欧&#xff09; 1 常见加密方式 2 对称加密 采用单钥密码系统的加密方法&#xff0c;同一个密钥可以同时用作信息的加密和解密&#xff0c;这种加密方法称为对称加密&#xff0c;也称为单密钥加密。 常见加密算法&#xff1a; DES : Data…...

实现Pytest测试用例按顺序循环执行多次

要实现测试用例按顺序循环执行多次&#xff0c;可以使用 pytest 的自定义装饰器或插件。这里有两种方法可以实现这个需求&#xff1a; 方法一&#xff1a;使用 pytest-repeat 插件 pytest-repeat 插件允许你重复执行测试用例。你可以使用 --count 参数来指定每个测试用例的执…...

SVN工作原理和使用示例

SVN&#xff08;Subversion&#xff09;是另一种版本控制系统&#xff0c;用于管理项目文件及其变更历史。与Git不同&#xff0c;SVN是集中式版本控制系统&#xff0c;这意味着所有版本控制操作都集中在一个中央服务器上。以下是SVN的工作原理和基本使用示例。 目录 SVN 工作…...

云服务器部署Java+Vue前后端分离项目

1、申请一个云服务器 选择云服务器&#xff1a;阿里云、腾讯云、百度云、京东云、华为云等等&#xff0c;我使用的是阿里云服务器。 2、远程链接服务器 使用FinalShell工具或者其他远程工具&#xff0c;使用SSH链接&#xff0c;主机地址要填写阿里云服务的公网ip&#xff0c;如…...