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官网

在这里插入图片描述

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

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

相关文章

浮毛季到了,拒绝猫咪变成“蒲公英”,宠物空气净化器去除浮毛

同为铲屎官&#xff0c;面对家中无处不在的猫毛挑战&#xff0c;想必你也深感头疼。衣物、沙发乃至地毯上的明显猫毛尚可通过吸尘器或粘毛器轻松应对&#xff0c;但那些细微漂浮的毛发却成了难以捉摸的“小恶魔”&#xff0c;普通的空气净化器往往力不从心。对于浮毛&#xff0…

分享安装Windows11系统相关的经验

文章目录 1. 概述2. 安装过程3. 经验分享本章回中我们准备向大家介绍如何安装 Window11操作系统同时分享一些相关的安装经验。 1. 概述 有看官说都什么年代了还介绍如何安装操作系统,不过介绍安装操作系统的方法不是我的重点,我的重点是分享相关的安装经验,帮助大家少走弯…

熵权法模型(评价类问题)

目录 本文章内容参考&#xff1a; 一. 概念 二. 特点 三. 实现步骤 四. 代码实现 本文章内容参考&#xff1a; 熵权法模型讲解(附matlab和python代码) 【数学建模快速入门】数模加油站 江北_哔哩哔哩_bilibili 一. 概念 利用信息熵计算各个指标的权重&#xff0c;从而为…

nvm 切换、安装 Node.js 版本

nvm下载路径 往下拉找到Assets 下载后&#xff0c;找到nvm-setup.exe双击&#xff0c;一直无脑下一步&#xff0c;即可安装成功。 配置环境变量&#xff08;我的是window11&#xff09; 打开任务栏设置–搜环境变量 配置好后&#xff0c;点确定一层一层关闭 windowR 打开控制…

Datawhale X 魔搭 AI夏令营 Task 01

Task 01 1. 注册阿里云 2. 跑通baseline 3. 生成图片并提交 后续思路&#xff1a; 调整prompt&#xff1b;更换微调数据集使用gpt生成故事简介

C++之类与对象(完结撒花篇)

目录 前言 1.再探构造函数 2.类型转换 3.static成员 4. 友元 5.内部类 6.匿名对象 7.对象拷贝时的编译器优化 结束语 前言 在前面的博客中&#xff0c;我们对类的默认成员函数都有了一定了解&#xff0c;同时实现了一个日期类对所学的没内容进行扩展延伸&#xff0c;本…

JavaWeb04-MyBatis与Spring结合

目录 前言 一、MyBatis入门&#xff08;MyBatis官网&#xff09; 1.1 创建mybatis项目&#xff08;使用spring项目整合式方法&#xff09; 1.2 JDBC 1.3 数据库连接池 1.4 实用工具&#xff1a;Lombok 二、MyBatis基础操作 2.1 准备工作 2.2 导入项目并实现操作 2.3 具…

Linux-Haproxy搭建Web群集

LVS在企业应用中抗负载能力强 不支持正则处理&#xff0c;不能实现动静分离对于大型网格&#xff0c;LVS的实施配置复杂&#xff0c;维护成本较高 Haproxy是一款可提供高可用性、负载均衡、及基于TCP和HTTP应用的代理的软件 适用于负载大的Web站点运行在硬件上可支持数以万计的…

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

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

Java二十三种设计模式-策略模式(13/23)

策略模式&#xff1a;灵活算法的替换与扩展 引言 策略模式&#xff08;Strategy Pattern&#xff09;是一种行为型设计模式&#xff0c;它定义了算法族&#xff0c;分别封装起来&#xff0c;让它们之间可以互相替换&#xff0c;此模式让算法的变化独立于使用算法的客户。 基础…

C#小结:如何在VS2022中使用菜单栏中的Git管理代码

目录 第一部分&#xff1a;基础操作 第一步&#xff0c;登录官网&#xff0c;设置好邮箱&#xff0c;然后右上角新建仓库 第二步&#xff0c;提交代码到远程仓库中 第三步&#xff0c;查看和比对自己修改的内容 第四步&#xff0c;查看该项目所有提交历史记录 第五步&…

嵌入式人工智能(OpenCV-基于树莓派的人脸识别与入侵检测)

1、人脸识别 人脸识别是一种技术&#xff0c;通过检测、跟踪和识别人脸上的关键特征&#xff0c;以确认人脸的身份。它通常用于安保系统、身份验证、社交媒体和人机交互等领域。 人脸识别技术的基本原理是先通过图像处理和计算机视觉算法&#xff0c;提取人脸的特征点和特征描…

【ML】Pre-trained Language Models及其各种微调模型的实现细节和特点

Pre-trained Language Models及其各种微调模型的实现细节和特点 1. Pre-trained Language Models2. semi-supervised Learning3. zero-shot4. Parameter-Efficient Fine-Tuning4.1 含义&#xff1a;4.2 实现方式&#xff1a; 5. LoRA5.1 LoRA 的主要特点&#xff1a;5.2 LoRA 的…

Pytorch人体姿态骨架生成图像

ControlNet是一个稳定扩散模型&#xff0c;可以复制构图和人体姿势。ControlNet解决了生成想要的确切姿势困难的问题。 Human Pose使用OpenPose检测关键点&#xff0c;如头部、肩膀、手的位置等。它适用于复制人类姿势&#xff0c;但不适用于其他细节&#xff0c;如服装、发型和…

Linux中apache服务安装与mysql安装

目录 一、apache安装 二、MySQL安装 一、apache安装 准备环境&#xff1a;一台虚拟机、三个安装包&#xff08;apr-1.6.2.tar.gz、apr-util-1.6.0.tar.gz、httpd-2.4.29.tar.bz2) 安装过程&#xff1a; tar xf apr-1.6.2.tar.gz tar xf apr-util-1.6.0.tar.gz tar xf http…

Burp Suite的使用和文件上传漏洞靶场试验

第一步&#xff1a;分析如何利用漏洞&#xff0c;通过对代码的查阅发现&#xff0c;代码的逻辑是先上传后删除&#xff0c;意味着&#xff0c;我可以利用webshell.php文件在上传到删除之间的间隙&#xff0c;执行webshell.php的代码&#xff0c;给上级目录创建一个shell.php木马…

IDEA右键新建时没有Java Class选项

项目场景&#xff1a; IDEA右键新建时没有Java Class选项 问题描述 IDEA右键新建时没有Java Class选项 原因分析&#xff1a; 提示&#xff1a;这里填写问题的分析&#xff1a; 例如&#xff1a;Handler 发送消息有两种方式&#xff0c;分别是 Handler.obtainMessage()和 Ha…

【扒代码】ope.py

文件目录&#xff1a; 引用方式 if not self.zero_shot: # 非零样本情况下&#xff0c;计算边界框的宽度和高度 box_hw torch.zeros(bboxes.size(0), bboxes.size(1), 2).to(bboxes.device) box_hw[:, :, 0] bboxes[:, :, 2] - bboxes[:, :, 0] # 宽度 box_hw[:, :, 1] bbox…

Docker in 100 Seconds

Docker a tool that can package software into containers that run reliably in any environment, but what is a container and why do you need one? Let’s imagine you built up an app with cobalt that runs some weird flavor of Linux. You want to share this app…

idea中好用的插件

输入法自动切换插件 自动切换输入法插件&#xff1a;Smart Input。编写代码时自动切换到英文输入法&#xff0c;注释代码自动切换为中文输入法。极大的提升我们的编码效率。 MyBatisX插件 MybatisX 是一款基于 IDEA 的快速开发插件&#xff0c;为效率而生。主要用于XML映射配…