Vue3使用Composition API实现响应式
title: Vue3使用Composition API实现响应式
date: 2024/5/29 下午8:10:24
updated: 2024/5/29 下午8:10:24
categories:
- 前端开发
tags:
- Vue3
- Composition
- Refs
- Reactive
- Watch
- Lifecycle
- Debugging
1. 介绍
Composition API是Vue.js 3中新增的一组API,用于在组件中组合逻辑和功能。它可以让你更好地组织和重用代码,使组件更易于理解和维护。在使用Composition
API时,你可以使用<script setup>
语法或setup()
函数,两种方式都可以使用Composition API中的响应式API、生命周期钩子、模板引用和自定义渲染函数等特性。
2. 基本响应式
在Vue.js 3中,Composition API提供了几种创建响应式数据的方法,包括ref
、reactive
、readonly
、shallowReactive
和shallowReadonly
。
2.1 ref
ref
函数用于创建一个响应式的ref对象,其值可以通过.value
属性获取或设置。当ref对象的值发生变化时,Vue.js会自动更新视图。AD:首页 | 一个覆盖广泛主题工具的高效在线平台
<template><div><p>count: {{ count }}</p><button @click="increment">+1</button></div>
</template><script setup>
import { ref } from 'vue';const count = ref(0);function increment() {count.value++;
}
</script>
2.2 reactive
reactive
函数用于创建一个响应式的对象,其所有属性都是响应式的。当对象的属性发生变化时,Vue.js会自动更新视图。
<template><div><p>name: {{ user.name }}</p><p>age: {{ user.age }}</p><button @click="incrementAge">+1</button></div>
</template><script setup>
import { reactive } from 'vue';const user = reactive({name: 'Alice',age: 20
});function incrementAge() {user.age++;
}
</script>
2.3 readonly
readonly
函数用于创建一个只读的响应式对象,其所有属性都是只读的。当试图修改只读对象的属性时,会抛出一个错误。
<template><div><p>name: {{ user.name }}</p><p>age: {{ user.age }}</p></div>
</template><script setup>
import { reactive, readonly } from 'vue';const user = reactive({name: 'Alice',age: 20
});const readonlyUser = readonly(user);// 会抛出一个错误
readonlyUser.age = 21;
</script>
2.4 shallowReactive
shallowReactive
函数用于创建一个浅响应式的对象,其所有属性都是响应式的,但其子对象的属性不是响应式的。
AD:专业搜索引擎
<template><div><p>name: {{ user.name }}</p><p>age: {{ user.age }}</p><p>address: {{ user.address }}</p><button @click="incrementAge">+1</button><button @click="changeAddress">改变地址</button></div>
</template><script setup>
import { shallowReactive } from 'vue';const user = shallowReactive({name: 'Alice',age: 20,address: {province: 'Beijing',city: 'Beijing'}
});function incrementAge() {user.age++;
}function changeAddress() {user.address = {province: 'Shanghai',city: 'Shanghai'};
}
</script>
2.5 shallowReadonly
shallowReadonly
函数用于创建一个浅只读的响应式对象,其所有属性都是只读的,但其子对象的属性不是只读的。
<template><div><p>name: {{ user.name }}</p><p>age: {{ user.age }}</p><p>address: {{ user.address }}</p><!-- 会抛出一个错误 --><button @click="changeAddress">改变地址</button></div>
</template><script setup>
import { shallowReactive, shallowReadonly } from 'vue';const user = shallowReactive({name: 'Alice',age: 20,address: {province: 'Beijing',city: 'Beijing'}
});const readonlyUser = shallowReadonly(user);// 会抛出一个错误
readonlyUser.age = 21;
</script>
3. 响应式API
Composition API提供了几种响应式API,包括watchEffect
、watch
、computed
和provide/inject
。
3.1 watchEffect
watchEffect
函数用于创建一个响应式的副作用函数,当响应式数据发生变化时,副作用函数会自动重新执行。
<template><div><p>count: {{ count }}</p><button @click="increment">+1</button></div>
</template><script setup>
import { ref, watchEffect } from 'vue';const count = ref(0);watchEffect(() => {console.log(`count is ${count.value}`);
});function increment() {count.value++;
}
</script>
3.2 watch
watch
函数用于创建一个响应式的监听器,当响应式数据发生变化时,监听器会自动执行。
<template><div><p>count: {{ count }}</p><button @click="increment">+1</button></div>
</template><script setup>
import { ref, watch } from 'vue';const count = ref(0);watch(count, (newValue, oldValue) => {console.log(`count changed from ${oldValue} to ${newValue}`);
});function increment() {count.value++;
}
</script>
3.3 computed
computed
函数用于创建一个响应式的计算属性,其值是根据响应式数据计算得出的。当响应式数据发生变化时,计算属性会自动重新计算。
AD:漫画首页
<template><div><p>count: {{ count }}</p><p>doubleCount: {{ doubleCount }}</p><button @click="increment">+1</button></div>
</template><script setup>
import { ref, computed } from 'vue';const count = ref(0);const doubleCount = computed(() => {return count.value * 2;
});function increment() {count.value++;
}
</script>
3.4 provide/inject
provide
和inject
函数用于在组件树中传递数据。provide
函数用于在父组件中提供数据,inject
函数用于在子组件中注入数据。
<template><div><ChildComponent /></div>
</template><script setup>
import { provide } from 'vue';
import ChildComponent from './ChildComponent.vue';provide('message', 'Hello, world!');
</script>
<template><div><p>{{ message }}</p></div>
</template><script setup>
import { inject } from 'vue';const message = inject('message');
</script>
4. 生命周期钩子
Composition
API提供了几种生命周期钩子,包括setup()
、onBeforeMount()
、onMounted()
、onBeforeUpdate()
、onUpdated()
、onBeforeUnmount()
、onUnmounted()
、onErrorCaptured()
、onRenderTracked()
和onRenderTriggered()
。
4.1 setup()
setup()
函数是Composition API的入口点,用于在组件创建之前执行一些初始化操作。
<template><div><p>count: {{ count }}</p><button @click="increment">+1</button></div>
</template><script>
import { ref } from 'vue';export default {setup() {const count = ref(0);function increment() {count.value++;}return {count,increment};}
};
</script>
4.2 onBeforeMount()
onBeforeMount()
函数在组件挂载之前执行。
<template><div><p>count: {{ count }}</p><button @click="increment">+1</button></div>
</template><script>
import { ref } from 'vue';export default {setup() {const count = ref(0);function increment() {count.value++;}onBeforeMount(() => {console.log('before mount');});return {count,increment};}
};
</script>
4.3 onMounted()
onMounted()
函数在组件挂载之后执行。
<template><div><p>count: {{ count }}</p><button @click="increment">+1</button></div>
</template><script>
import { ref } from 'vue';export default {setup() {const count = ref(0);function increment() {count.value++;}onMounted(() => {console.log('mounted');});return {count,increment};}
};
</script>
4.4 onBeforeUpdate()
onBeforeUpdate()
函数在组件更新之前执行。
<template><div><p>count: {{ count }}</p><button @click="increment">+1</button></div>
</template><script>
import { ref } from 'vue';export default {setup() {const count = ref(0);function increment() {count.value++;}onBeforeUpdate(() => {console.log('before update');});return {count,increment};}
};
</script>
4.5 onUpdated()
onUpdated()
函数在组件更新之后执行。
<template><div><p>count: {{ count }}</p><button @click="increment">+1</button></div>
</template><script>
import { ref } from 'vue';export default {setup() {const count = ref(0);function increment() {count.value++;}onUpdated(() => {console.log('updated');});return {count,increment};}
};
</script>
4.6 onBeforeUnmount()
onBeforeUnmount()
函数在组件卸载之前执行。
<template><div><p>count: {{ count }}</p><button @click="increment">+1</button></div>
</template><script>
import { ref } from 'vue';export default {setup() {const count = ref(0);function increment() {count.value++;}onBeforeUnmount(() => {console.log('before unmount');});return {count,increment};}
};
</script>
4.7 onUnmounted()
onUnmounted()
函数在组件卸载之后执行。
<template><div><p>count: {{ count }}</p><button @click="increment">+1</button></div>
</template><script>
import { ref } from 'vue';export default {setup() {const count = ref(0);function increment() {count.value++;}onUnmounted(() => {console.log('unmounted');});return {count,increment};}
};
</script>
4.8 onErrorCaptured()
onErrorCaptured()
函数在组件捕获到错误时执行。
<template><div><p>count: {{ count }}</p><button @click="increment">+1</button></div>
</template><script>
import { ref } from 'vue';export default {setup() {const count = ref(0);function increment() {count.value++;}onErrorCaptured((error, instance, info) => {console.error(error);return false;});return {count,increment};}
};
</script>
4.9 onRenderTracked
和 onRenderTriggered
onRenderTracked
和onRenderTriggered
是两个生命周期钩子,它们与Vue的响应式系统和编译器有关。这两个钩子是在Vue
3.x版本中引入的,主要用于调试目的,帮助开发者了解组件渲染过程中的跟踪和触发情况。
-
onRenderTracked
钩子:- 当组件的响应式依赖项被追踪时,即响应式系统开始跟踪一个依赖项时,这个钩子会被调用。
- 它主要用于调试,可以帮助开发者了解何时响应式系统开始关注某个依赖项。
onRenderTracked
钩子接收两个参数:dep
和context
。dep
是依赖项对象,context
是当前组件的上下文对象。
-
onRenderTriggered
钩子:- 当组件的响应式依赖项被触发时,即响应式系统因为某个依赖项的变化而触发了重新渲染时,这个钩子会被调用。
- 它主要用于调试,可以帮助开发者了解何时响应式系统因为某个依赖项的变化而重新渲染组件。
onRenderTriggered
钩子也接收两个参数:dep
和context
,含义与onRenderTracked
相同。
示例代码:
export default {setup() {// 定义一个响应式数据const count = ref(0);// 监听 count 的变化watch(count, (newValue, oldValue) => {console.log(`count changed from ${oldValue} to ${newValue}`);});// 使用 onRenderTracked 和 onRenderTriggered 进行调试onRenderTracked((dep, context) => {console.log(`onRenderTracked: ${dep}`);});onRenderTriggered((dep, context) => {console.log(`onRenderTriggered: ${dep}`);});return {count};}
};
在这个示例中,我们定义了一个响应式数据count
,并使用了watch
来监听它的变化。同时,我们使用了onRenderTracked
和onRenderTriggered
来打印调试信息。当响应式系统开始跟踪或触发重新渲染时,我们会得到相应的提示。这些钩子可以帮助开发者更好地理解Vue组件的渲染过程和响应式系统的运作。
相关文章:

Vue3使用Composition API实现响应式
title: Vue3使用Composition API实现响应式 date: 2024/5/29 下午8:10:24 updated: 2024/5/29 下午8:10:24 categories: 前端开发 tags: Vue3CompositionRefsReactiveWatchLifecycleDebugging 1. 介绍 Composition API是Vue.js 3中新增的一组API,用于在组件中组…...

使用moquette mqtt发布wss服务
文章目录 概要一、制作的ssl证书二、配置wss小结 概要 moquette是一款不错的开源mqtt中间件,github地址:https://github.com/moquette-io/moquette。我们在发布mqtt服务的同时,是可以提供websocket服务器的,有些场景下需要用到&a…...

【笔记】软件架构师要点记录(2)
【笔记】软件架构师要点记录 20240523案例一案例二案例三案例四案例五案例六案例七案例十 20240523 基于前10个架构案例场景,对用到的专业术语进行整理,方便后续查看。 案例一 MVC架构风格组件交互方式 MVC是一种用来构建用户界面时采用的架构设计风格…...
56.野指针和悬空指针
一.野指针 野指针指的是指针指向的地址是未知的(随机的,不正确的地址)。 二.野指针出现的几种情况 1.定义指针未初始化 #include <stdio.h>int main(void) {int *p;*p 1;printf("*p is %d\n",*p); } 正确写法࿱…...

echarts-dataset,graphic,dataZoom, toolbox
dataset数据集配置数据 dataset数据集,也可以完成数据的映射,一般用于一段数据画多个图表 例子: options {tooltip: {},dataset: {source: [["product", "2015", "2016", "2017"],["test&q…...
AI界的“拼夕夕”登场,为上万张GPU寻找新使命
在AI领域,一个全新的竞争者已经悄然登场。 AI行业果真有着近乎颠覆性的魅力! 此次事件之后,AI界也许会迎来新一轮的血雨腥风! AI的潮流到底会怎样流转,天知道。 幻方量化,这家以量化投资闻名的公司&…...

STM32-13-MPU
STM32-01-认识单片机 STM32-02-基础知识 STM32-03-HAL库 STM32-04-时钟树 STM32-05-SYSTEM文件夹 STM32-06-GPIO STM32-07-外部中断 STM32-08-串口 STM32-09-IWDG和WWDG STM32-10-定时器 STM32-11-电容触摸按键 STM32-12-OLED模块 文章目录 STM32-12-MPU1. 内存保护单元MPU1. M…...

(超详细)字符函数和字符串函数【上】
前言 C 语言中对字符和字符串的处理很是频繁,但是 C 语言本身是没有字符串类型的,字符串通常放在 常量字符串 中或者 字符数组 中。 字符串常量 适用于那些对它不做修改的字符串函数 . 1.求字符串长度函数 strlen函数 我们要求一个字符串函数的长度…...

AUS GLOBAL 荣获 Brokersview 颁奖盛典多项殊荣
2024年1月31日在迪拜 Sheikh Zayed Rd - Trade Centre - Trade Centre 1 举行的 Brokersview 颁奖盛典上,AUS GLOBAL(澳洲环球)再次展现了其在金融行业的卓越实力,并荣获多项殊荣。 AUS GLOBAL 作为一家全球领先的金融服务提供商…...
Spring Aop 实现对mapper层入参进行重新赋值
需求描述: 需要对mapper查询的入参的某个属性值进行特殊处理后查询 不影响原来业务且方便扩展维护 1,自定义注解 import java.lang.annotation.*;/*** 针对 mapper层入参 按照一定规则进行特殊处理重新赋值*/ Target(ElementType.METHOD) Retention(Ret…...

朗读亭主要作用有哪些?
朗读亭的主要作用有以下几个方面: 1. 提供朗读服务:朗读亭是一个专门的场所,提供给人们朗读的环境和场地。人们可以在朗读亭中选择自己喜欢的书籍或文章,并通过朗读将其表达出来。这样可以帮助人们提高朗读能力,增强自…...

力扣:226. 翻转二叉树
226. 翻转二叉树 已解答 简单 相关标签 相关企业 给你一棵二叉树的根节点 root ,翻转这棵二叉树,并返回其根节点。 示例 1: 输入:root [4,2,7,1,3,6,9] 输出:[4,7,2,9,6,3,1]示例 2: 输入:…...

深入解析 JSONPath:从入门到精通
码到三十五 : 个人主页 在数据处理和交换领域,JSON已经成为了一种广泛使用的数据格式, 如何有效地查询和操作这些数据也变得越来越重要。在这种情况下,JSONPath 应运而生,成为了一种在JSON数据中定位和提取信息的强大工…...
Python算法设计与分析期末
Python算法设计与分析期末通常涉及对算法基础知识的理解和应用,包括但不限于以下几个方面: 算法基础:了解算法的定义、特性(确定性、有穷性、可行性等)以及算法的分类。 时间复杂度和空间复杂度:学会分析算…...

pg_lakehouse 与 datafusion
原理分析 pg_lakehouse 是 ParadeDB 推出的一个开源插件,支持对多种数据湖里的数据做分析计算。它的出现,使得 Postgres 能够像访问本地数据一样轻松访问 S3 等对象存储,轻松访问 Delta Lake 上的表格,具备数据湖分析能力。 pg_…...

基于51单片机的酒精浓度检测仪的设计
一.硬件方案 硬件部分为利用MQ3气敏传感器测量空气中酒精浓度,并转换为电压信号,经A/D转换器转换成数字信号后传给单片机系统,由单片机及其相应外围电路进行信号的处理,显示酒精浓度值以及超阈值声光报警。电路主要由51单片机最小…...

重生之 SpringBoot3 入门保姆级学习(02、打包部署)
重生之 SpringBoot3 入门保姆级学习(02、打包部署) 1.6 打包插件1.7 测试 jar 包1.8 application.properties 的相关配置 1.6 打包插件 官网链接 https://docs.spring.io/spring-boot/docs/current/reference/html/getting-started.html#getting-starte…...
Java-常用模块
文章目录 日期时间stream流 日期时间 jdk8新的日期时间类 解析和格式化DateTimeFormatter类(线程安全) LocalDateTime类 Instant类 Duration类String time "2013-02-11 11:00:00";DateTimeFormatter dateTimeFormatter DateTimeFormatter.o…...
c++大作业 调整字幕的时间
作业及其需求 有时候人们能够下载一些感兴趣的视频但是发现并没有字幕,到字幕网站上查找到字幕文件,但是发现时间进度上不能完美配合,一个视频数据的例子来源于链接: BBC.巴塔哥尼亚:地球秘密乐园 https://www.aliyundrive.com/s/LmF2sgrQzMu/folder/612af030c6fa4bf4b7c…...
Nmap使用方法
Nmap 介绍 Nmap是一个免费开放的网络扫描和嗅探工具包,也叫网络映射器(Network Mapper)。该工具其基本功能有三个,一是探测一组主机是否在线;其次是扫描主机端口,嗅探所提供的网络服务;三是可…...
golang循环变量捕获问题
在 Go 语言中,当在循环中启动协程(goroutine)时,如果在协程闭包中直接引用循环变量,可能会遇到一个常见的陷阱 - 循环变量捕获问题。让我详细解释一下: 问题背景 看这个代码片段: fo…...
【位运算】消失的两个数字(hard)
消失的两个数字(hard) 题⽬描述:解法(位运算):Java 算法代码:更简便代码 题⽬链接:⾯试题 17.19. 消失的两个数字 题⽬描述: 给定⼀个数组,包含从 1 到 N 所有…...

关于nvm与node.js
1 安装nvm 安装过程中手动修改 nvm的安装路径, 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解,但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后,通常在该文件中会出现以下配置&…...

家政维修平台实战20:权限设计
目录 1 获取工人信息2 搭建工人入口3 权限判断总结 目前我们已经搭建好了基础的用户体系,主要是分成几个表,用户表我们是记录用户的基础信息,包括手机、昵称、头像。而工人和员工各有各的表。那么就有一个问题,不同的角色…...

【Zephyr 系列 10】实战项目:打造一个蓝牙传感器终端 + 网关系统(完整架构与全栈实现)
🧠关键词:Zephyr、BLE、终端、网关、广播、连接、传感器、数据采集、低功耗、系统集成 📌目标读者:希望基于 Zephyr 构建 BLE 系统架构、实现终端与网关协作、具备产品交付能力的开发者 📊篇幅字数:约 5200 字 ✨ 项目总览 在物联网实际项目中,**“终端 + 网关”**是…...

第 86 场周赛:矩阵中的幻方、钥匙和房间、将数组拆分成斐波那契序列、猜猜这个单词
Q1、[中等] 矩阵中的幻方 1、题目描述 3 x 3 的幻方是一个填充有 从 1 到 9 的不同数字的 3 x 3 矩阵,其中每行,每列以及两条对角线上的各数之和都相等。 给定一个由整数组成的row x col 的 grid,其中有多少个 3 3 的 “幻方” 子矩阵&am…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...

优选算法第十二讲:队列 + 宽搜 优先级队列
优选算法第十二讲:队列 宽搜 && 优先级队列 1.N叉树的层序遍历2.二叉树的锯齿型层序遍历3.二叉树最大宽度4.在每个树行中找最大值5.优先级队列 -- 最后一块石头的重量6.数据流中的第K大元素7.前K个高频单词8.数据流的中位数 1.N叉树的层序遍历 2.二叉树的锯…...

Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习)
Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习) 一、Aspose.PDF 简介二、说明(⚠️仅供学习与研究使用)三、技术流程总览四、准备工作1. 下载 Jar 包2. Maven 项目依赖配置 五、字节码修改实现代码&#…...

CVE-2020-17519源码分析与漏洞复现(Flink 任意文件读取)
漏洞概览 漏洞名称:Apache Flink REST API 任意文件读取漏洞CVE编号:CVE-2020-17519CVSS评分:7.5影响版本:Apache Flink 1.11.0、1.11.1、1.11.2修复版本:≥ 1.11.3 或 ≥ 1.12.0漏洞类型:路径遍历&#x…...