Vue3从零开始——掌握setup、ref和reactive函数的奥秘
文章目录
- 一、Vue 3 组合式 API 概述
- 二、`setup` 函数的基本使用
- 2.1 `setup` 函数的特点
- 2.2 `setup` 函数的基本结构
- 2.3 实现一个简单的小demo
- 三、`ref` 函数的功能和应用
- 3.1 `ref`函数介绍
- 3.2 基本使用
- 3.2.1 定义`ref`数据
- 3.2.2 修改响应式变量
- 3.3 使用`ref`函数实现计数器
- 四、`reactive` 函数的功能和应用
- 4.1 `reactive` 函数介绍
- 4.2 基本使用
- 4.3 使用`reactive`函数实现计数器
- 4.4 `reactive`函数的的局限性
- 五、`ref` 与 `reactive` 的区别
- 5.1 主要区别
- 5.2 `ref` 适合的场景
- 5.3 `reactive` 适合的场景
- 5.4 Vue社区观点
- 六、总结

一、Vue 3 组合式 API 概述
在 Vue 3 中,引入了组合式 API(Composition API) ,这使得开发者可以更灵活地组织代码逻辑,并提升了组件的复用性和可维护性。相比于 Vue 2 中的选项式 API,组合式 API 提供了一种更具功能性的方式来构建应用。
主要优点:
- 逻辑复用和组织:通过组合函数可以更清晰地组织代码逻辑,避免在生命周期函数中写大量逻辑。
- 更好的 TypeScript 支持:组合式 API 天然地支持 TypeScript,这使得类型推断和类型检查变得更加轻松。
- 性能优化:组合式 API 的实现方式在某些场景下可以带来性能上的提升。
二、setup
函数的基本使用
setup
函数是 Vue 3 组件中使用组合式 API 的起点,它是一个新增加的组件选项,所有的组合式 API 的逻辑都需要在这个函数中书写。
2.1 setup
函数的特点
- 从组件生命周期来看,在
beforeCreate
之前调用,因此它没有this
绑定。 - 函数中
this
不是组件实例,是undefined
。 - 返回一个对象,该对象将被合并到组件的
data
中,可以在模板中直接使用。
2.2 setup
函数的基本结构
<template><div><!-- 绑定在模板中的变量和方法 --></div>
</template><script>
import { ref, reactive } from 'vue';export default {setup() {// 在这里定义响应式变量和方法return {// 返回需要在模板中使用的变量和方法};},
};
</script><style scoped>
/* 样式部分 */
</style>
2.3 实现一个简单的小demo
<template><div><p @click="show()">{{ msg }}</p></div>
</template><script>export default {setup() {console.log("setup 函数执行了");let msg = 'Hello World';function show(){console.log("show 函数执行了");}// 返回定义的变量和函数return {msg,show};},beforeCreate() {console.log("beforeCreate 函数执行了");},
};
</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
函数的功能和应用
3.1 ref
函数介绍
ref
函数用于创建一个持有单个值的响应式引用。它适用于基本数据类型(如字符串、数字、布尔值)和不需要深度响应的数据结构。通过 ref
函数,我们可以在 Vue 组件中创建简单的响应式数据。
主要特点:
- 基本类型响应性:为基本数据类型创建响应式状态。
- 引用式访问:通过
.value
属性访问和修改值。 - 适用于 DOM 引用:可以用于 DOM 元素的引用。
3.2 基本使用
3.2.1 定义ref
数据
import { ref } from 'vue';export default {setup() {// 创建响应式数据const count = ref(0); const message = ref('Hello, Vue 3!');const isVisible = ref(true);return {count,message,isVisible,};},
};
3.2.2 修改响应式变量
要修改 ref
创建的响应式变量,需要使用 .value
属性:
count.value++; // 增加 count
count.value = 10; // 设置 count 的值
注意:当在Vue的模板(
template
)中使用时,ref
的值可以直接使用,无需显式调用.value
:<template><div><p>{{ count }}</p><button @click="count++">增加</button></div> </template>
3.3 使用ref
函数实现计数器
应用需求:
- 显示当前计数。
- 提供按钮增加计数。
- 提供按钮重置计数。
<template><div><p>当前计数:{{ count }}</p><button @click="increment">增加</button><button @click="reset">重置</button></div>
</template><script>
import { ref } from 'vue';export default {setup() {console.log("setup 函数执行了");// 创建一个响应式对象const count = ref(0);// 增加计数function increment() {count.value++;console.log("count = " + count.value);}// 重置计数function reset() {count.value = 0;}return {count,increment,reset,};},beforeCreate() {console.log("beforeCreate 函数执行了");},
};
</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
创建一个响应式变量count
实现记录数字。ref(0)
表示将初始值设置为0
。- 定义方法:
increment
方法:用于增加计数值。在函数内部,通过count.value++
来递增计数器,并在控制台中输出新的计数值。reset
方法:用于重置计数值。将count.value
设为0
来重置计数器。- 组件返回:
return
:返回count
和方法increment
、reset
,使其在模板中可以直接访问,这一步非常重要!!- 模板绑定:
{{ count }}
:在模板中使用双花括号语法绑定count
,动态显示当前计数值。@click
:绑定button
元素的点击事件到increment
和reset
函数上,实现按钮点击后对计数值的增加和重置。- 生命周期钩子:
beforeCreate
:输出消息以便于理解setup
函数的执行顺序。
四、reactive
函数的功能和应用
4.1 reactive
函数介绍
reactive
是 Vue 3 提供的一个 API,用于创建深度响应式对象。与 ref
不同,ref
适用于基本数据类型,而 reactive
更适用于对象、数组等复杂数据结构。
主要特点:
- 创建深度响应式的数据对象。
- 自动跟踪依赖变化并更新视图。
- 可以结合
toRefs
解构成多个响应式引用。
4.2 基本使用
import { reactive } from 'vue';export default {setup() {// 创建响应式对象const state = reactive({count: 0,message: 'Hello, Vue 3!',});// 方法示例function increment() {state.count++;}return {state,increment,};},
};
在上面的代码中,我们使用 reactive
创建了一个响应式对象 state
,其中包含了两个属性:count
和 message
。increment
函数可以用来增加 count
的值。
4.3 使用reactive
函数实现计数器
应用需求:
- 显示当前计数。
- 提供按钮增加计数。
- 提供按钮重置计数。
<template><div><h1>{{ state.title }}</h1><p>当前计数:{{ state.count }}</p><button @click="increment">增加</button><button @click="reset">重置</button></div>
</template><script>
import { reactive } from 'vue';export default {setup() {// 创建一个响应式对象const state = reactive({count: 0,title: '计数器应用',});// 增加计数function increment() {state.count++;}// 重置计数function reset() {state.count = 0;}// 暴露定义的数据和函数return {state,increment,reset,};},
};
</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;
}h1 {color: #333;
}p {font-size: 18px;
}
</style>
代码解读:
跟前面的其实差不多,只不过用法上有一点区别,其他其实差别并不大。
- 创建响应式变量:使用
ref
创建两个响应式变量count
和title
。- 定义方法:定义
increment
和decrement
函数,用于增加和减少计数。- 模板绑定:在模板中使用
{{ }}
绑定响应式变量,并通过@click
指令绑定事件处理函数。
4.4 reactive
函数的的局限性
参考自:https://cn.vuejs.org/guide/essentials/reactivity-fundamentals.html#reactive
reactive()
API 有一些局限性:
-
有限的值类型:它只能用于对象类型 (对象、数组和如
Map
、Set
这样的集合类型)。它不能持有如string
、number
或boolean
这样的原始类型。 -
不能替换整个对象:由于 Vue 的响应式跟踪是通过属性访问实现的,因此我们必须始终保持对响应式对象的相同引用。这意味着我们不能轻易地“替换”响应式对象,因为这样的话与第一个引用的响应性连接将丢失:
jslet state = reactive({ count: 0 })// 上面的 ({ count: 0 }) 引用将不再被追踪 // (响应性连接已丢失!) state = reactive({ count: 1 })
-
对解构操作不友好:当我们将响应式对象的原始类型属性解构为本地变量时,或者将该属性传递给函数时,我们将丢失响应性连接:
jsconst state = reactive({ count: 0 })// 当解构时,count 已经与 state.count 断开连接 let { count } = state // 不会影响原始的 state count++// 该函数接收到的是一个普通的数字 // 并且无法追踪 state.count 的变化 // 我们必须传入整个对象以保持响应性 callSomeFunction(state.count)
由于这些限制,我们建议使用 ref()
作为声明响应式状态的主要 API。
五、ref
与 reactive
的区别
Vue 3 提供了两种创建响应式数据的方式:ref
和 reactive
。它们在功能上有一些不同,适用于不同的场景。
5.1 主要区别
特性 | ref | reactive |
---|---|---|
用途 | 创建持有基本类型值的响应式引用 | 创建深度响应式对象,适合复杂数据结构 |
访问方式 | 通过.value 访问和修改 | 直接访问和修改对象的属性 |
响应性 | 基本类型响应性 | 深度响应性,自动追踪对象属性的变化 |
适用场景 | 适用于简单的状态和需要 DOM 引用的场景 | 适用于多属性对象、数组、复杂数据结构 |
数据类型支持 | 只对 object 类型有效 | 对任意类型有效 |
使用方式 | 在 <script> 和 <template> 中无差别使用 | 在 <script> 和 <template> 使用方式不同 |
5.2 ref
适合的场景
- 用于基本类型或需要独立响应式的变量。适合处理简单的数据类型,如
Number
、String
、Boolean
。 - 独立的响应式变量:需要单独处理或跟踪的变量。
- DOM 元素引用:通过
ref
获取和操作 DOM 元素。
5.3 reactive
适合的场景
- 用于复杂的数据结构,如对象或数组。适合处理多属性的对象或需要整个结构响应式的数据。
- 深度响应:需要自动跟踪嵌套属性变化的数据。
5.4 Vue社区观点
默认都使用 ref
,当需要分组时使用 reactive
。
详细原因可以看:Ref vs. Reactive — Which is Best? | Michael Thiessen
六、总结
本文主要讲述了 Vue 3 中的 setup
函数、ref
函数和 reactive
函数的一些基本知识,他们的基本使用语法和如何简单运用实现一个小demo,希望对大家有所帮助☺️。
参考文章:
Ref vs. Reactive — Which is Best? | Michael Thiessen
【译】Ref vs. Reactive:使用Vue3组合式API该如何选择?
响应式基础 | Vue.js
相关文章:

Vue3从零开始——掌握setup、ref和reactive函数的奥秘
文章目录 一、Vue 3 组合式 API 概述二、setup 函数的基本使用2.1 setup 函数的特点2.2 setup 函数的基本结构2.3 实现一个简单的小demo 三、ref 函数的功能和应用3.1 ref函数介绍3.2 基本使用3.2.1 定义ref数据3.2.2 修改响应式变量 3.3 使用ref函数实现计数器 …...
C语言练习--屏幕上打印九九乘法表
int main() { int i 0; for (i 1; i < 10; i) { int j 0; for (j 1; j <i; j) { printf(" %d*%d%2d", i, j, i * j); } printf("\n"); } return 0; }...

将tsx引入vue
按钮 vue <cl-batch-btn >新增批量</cl-batch-btn> import batch from "//modules/ad/components/ uploading/batch.vue" import ClBatchBtn from "/~/crud/src/components/batch-btn"; tsx...

前端实现签字效果+合同展示
文章目录 获取一个高度会变的元素的高度获取元素设置的 transform适配手机transform-origin: 5% 0; 的原因修改后 签字效果取消el-dialog的头部边距为什么禁止界面滚动vue3 使用 nextTick实现效果 签字判断是横是竖canvas 去掉空白部分canvas裁剪图片最终完善代码,可…...
[AI Embedchain] 开始使用 - 快速开始
安装 首先安装 Python 包: pip install embedchain安装包后,根据您的偏好,您可以选择使用以下内容: 开源模型 本节提供了一个快速入门示例,展示了如何使用 Mistral 作为开源 LLM(大型语言模型ÿ…...
Linux网络协议.之 tcp,udp,socket网络编程(三).之多进程实现并发demon
一、fork创建进程,来实现多并发 这只是个demon,并不能用于实际项目,多进程,消耗太多资源。没有人这么玩 1、服务端代码: #include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #in…...
Java线程(练习题)
Exercise 创建三个线程:一个线程打印 100个A,一个线程打印 100 个 B ,一个线程打印 100个C 输出效果:ABC ABC ABC…交替打印 package com.kane.exercise01;public class PrintABC implements Runnable {private static final Object lock …...

MySQL:初识数据库初识SQL建库
目录 1、初识数据库 1.1 什么是数据库 1.2 什么是MySQL 2、数据库 2.1 数据库服务&数据库 2.2 C/S架构 3、 初识SQL 3.1 什么是SQL 3.2 SQL分类 4、使用SQL 4.1 查看所有数据库 4.1.2 语句解析 4.2 创建数据库 4.2.1 if not exists校验 4.2.2 手动明确字符集…...

关于Redis的集群面试题
问题一:Redis的多数据库机制,了解多少? Redis支持多个数据库,并且每个数据库是隔离的不能共享,单机下的redis可以支持16个数据库(db0~db15);若在Redis Cluster集群架构下,则只有一个…...
带头双向循环链表(一)
今天我们来学习带头双向链表 带头双向循环链表的解释 带头双向链表顾名思义就是: 1、带了一个“头”在数据结构中的意思就是加了一个"哨兵位"。 2、这个链表是双向循环的链表即可以通过任意的节点访问它的上一个和下一个的节点也能通过链表的头直接访…...
深入理解Win32K.sys的工作原理
https://download.csdn.net/download/sitelist/89621815 Windows Resource Kits 2003.rar工具下载,因为有windows server 2003源代码,并可以编译成iso,所以对于研究windows系统很有帮助,上吗是2003的研究工具,不知道源…...

力扣面试经典算法150题:删除有序数组中的重复项
删除有序数组中的重复项 今天的题目是力扣面试经典150题中的数组的简单题: 删除有序数组中的重复项 题目链接:https://leetcode.cn/problems/remove-duplicates-from-sorted-array/description/?envTypestudy-plan-v2&envIdtop-interview-150 题目描述 给定一…...

文本加密工具类-支持MD5、SHA1、SHA256、SHA224、SHA512、SHA384、SHA3、RIPMD160算法
文本加密工具类 1.算法简介1.1 MD51.2 SHA-11.3 SHA-2(推荐使用)1.4 SHA-3(推荐使用)1.5 RIPEMD-160 2.工具类案例2.1POM导入2.2代码编写2.3 输出示例 1.算法简介 1.1 MD5 MD5 (Message-Digest Algorithm 5) 描述:M…...

LVS集群中的负载均衡技术
目录 一、LVS技术原理 二、NAT模式原理及部署方法 1、工作原理 2、部署方法 1、网络配置 2、软件安装与启用 3、测试 三、DR模式原理及部署方法 1、工作原理 2、部署方法 1、网络配置 2、解决vip响应问题 3、测试 四、ipvsadm命令及参数 1、管理集群服务&#x…...

Java网络编程——HTTP协议原理
协议 我们在网上冲浪时,会在浏览器地址栏输入一个网址,然后就能打开网页了。比如,输入 https://www.douban.com/就可以访问到豆瓣的主页: 那么大家是否好奇:https 是什么意思,作用又是什么呢?…...

java之多线程篇
一、基本概念 1.什么是线程? 线程就是,操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。简单理解就是:应用软件中互相独立,可以同时运行的功能 2.什么是多线程? 有了多线…...
【深度学习】TTS,CosyVoice,训练脚本解析
https://github.com/FunAudioLLM/CosyVoice/blob/main/examples/libritts/cosyvoice/run.sh Bash 脚本是一个语音合成(TTS)训练和推理的完整流水线。让我们逐步解析这个脚本的各个部分。 初始化部分 #!/bin/bash # Copyright 2024 Alibaba Inc. All Rights Reserved. . ./…...

《Unity3D网络游戏实战》学习与实践
纸上得来终觉浅,绝知此事要躬行~ Echo 网络上的两个程序通过一个双向的通信连接实现数据交换,这个连接的一端称为一个Socket “端口”是英文port的意译,是设备与外界通信交流的出口。每台计算机可以分配0到65535共65536个端口 每一条Sock…...

Machine_Matrix打靶渗透【附代码】(权限提升)
靶机下载地址: https%3A%2F%2Fdownload.vulnhub.com%2Fmatrix%2FMachine_Matrix.zip 1. 主机发现端口扫描目录扫描敏感信息获取 1.1. 主机发现 nmap -sn 192.168.7.0/24|grep -B 2 08:00:27:D9:36:81 1.2. 端口扫描 nmap -p- 192.168.7.155 1.3. 目录扫描 dir…...

代码随想录算法训练营Day22 | Leetcode 77 组合 Leetcode 216 组合总和Ⅲ Leetcode17 电话号码的字母组合
前言 回溯算法中递归的逻辑不重要,只要掌握回溯的模板以及将问题转化为树形图,整个问题就很好解决了,比二叉树简单。 Leetcode 77 组合 题目链接:77. 组合 - 力扣(LeetCode) 代码随想录题解:…...
反向工程与模型迁移:打造未来商品详情API的可持续创新体系
在电商行业蓬勃发展的当下,商品详情API作为连接电商平台与开发者、商家及用户的关键纽带,其重要性日益凸显。传统商品详情API主要聚焦于商品基本信息(如名称、价格、库存等)的获取与展示,已难以满足市场对个性化、智能…...

关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案
问题描述:iview使用table 中type: "index",分页之后 ,索引还是从1开始,试过绑定后台返回数据的id, 这种方法可行,就是后台返回数据的每个页面id都不完全是按照从1开始的升序,因此百度了下,找到了…...

基于当前项目通过npm包形式暴露公共组件
1.package.sjon文件配置 其中xh-flowable就是暴露出去的npm包名 2.创建tpyes文件夹,并新增内容 3.创建package文件夹...
【Go】3、Go语言进阶与依赖管理
前言 本系列文章参考自稀土掘金上的 【字节内部课】公开课,做自我学习总结整理。 Go语言并发编程 Go语言原生支持并发编程,它的核心机制是 Goroutine 协程、Channel 通道,并基于CSP(Communicating Sequential Processes࿰…...
JS设计模式(4):观察者模式
JS设计模式(4):观察者模式 一、引入 在开发中,我们经常会遇到这样的场景:一个对象的状态变化需要自动通知其他对象,比如: 电商平台中,商品库存变化时需要通知所有订阅该商品的用户;新闻网站中࿰…...

Linux nano命令的基本使用
参考资料 GNU nanoを使いこなすnano基础 目录 一. 简介二. 文件打开2.1 普通方式打开文件2.2 只读方式打开文件 三. 文件查看3.1 打开文件时,显示行号3.2 翻页查看 四. 文件编辑4.1 Ctrl K 复制 和 Ctrl U 粘贴4.2 Alt/Esc U 撤回 五. 文件保存与退出5.1 Ctrl …...

毫米波雷达基础理论(3D+4D)
3D、4D毫米波雷达基础知识及厂商选型 PreView : https://mp.weixin.qq.com/s/bQkju4r6med7I3TBGJI_bQ 1. FMCW毫米波雷达基础知识 主要参考博文: 一文入门汽车毫米波雷达基本原理 :https://mp.weixin.qq.com/s/_EN7A5lKcz2Eh8dLnjE19w 毫米波雷达基础…...

零知开源——STM32F103RBT6驱动 ICM20948 九轴传感器及 vofa + 上位机可视化教程
STM32F1 本教程使用零知标准板(STM32F103RBT6)通过I2C驱动ICM20948九轴传感器,实现姿态解算,并通过串口将数据实时发送至VOFA上位机进行3D可视化。代码基于开源库修改优化,适合嵌入式及物联网开发者。在基础驱动上新增…...
人工智能 - 在Dify、Coze、n8n、FastGPT和RAGFlow之间做出技术选型
在Dify、Coze、n8n、FastGPT和RAGFlow之间做出技术选型。这些平台各有侧重,适用场景差异显著。下面我将从核心功能定位、典型应用场景、真实体验痛点、选型决策关键点进行拆解,并提供具体场景下的推荐方案。 一、核心功能定位速览 平台核心定位技术栈亮…...

2.3 物理层设备
在这个视频中,我们要学习工作在物理层的两种网络设备,分别是中继器和集线器。首先来看中继器。在计算机网络中两个节点之间,需要通过物理传输媒体或者说物理传输介质进行连接。像同轴电缆、双绞线就是典型的传输介质,假设A节点要给…...