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提供了几种创建响应式数据的方法,包括refreactivereadonlyshallowReactive
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,包括watchEffectwatchcomputedprovide/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

provideinject函数用于在组件树中传递数据。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 onRenderTrackedonRenderTriggered

onRenderTrackedonRenderTriggered是两个生命周期钩子,它们与Vue的响应式系统和编译器有关。这两个钩子是在Vue
3.x版本中引入的,主要用于调试目的,帮助开发者了解组件渲染过程中的跟踪和触发情况。

  1. onRenderTracked钩子:

    • 当组件的响应式依赖项被追踪时,即响应式系统开始跟踪一个依赖项时,这个钩子会被调用。
    • 它主要用于调试,可以帮助开发者了解何时响应式系统开始关注某个依赖项。
    • onRenderTracked钩子接收两个参数:depcontextdep是依赖项对象,context是当前组件的上下文对象。
  2. onRenderTriggered钩子:

    • 当组件的响应式依赖项被触发时,即响应式系统因为某个依赖项的变化而触发了重新渲染时,这个钩子会被调用。
    • 它主要用于调试,可以帮助开发者了解何时响应式系统因为某个依赖项的变化而重新渲染组件。
    • onRenderTriggered钩子也接收两个参数:depcontext,含义与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组件的渲染过程和响应式系统的运作。

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

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

相关文章

Python 之微信指数小程序数据抓取

Fiddler安装和设置 安装 Fiddler 安装包可以从这里获取&#xff0c;如果失效了可以自己网上找一个安装。 链接&#xff1a;https://pan.baidu.com/s/1N30BoDWm2_dBL8i8GRzK5g?pwd1znv 提取码&#xff1a;1znv 然后就是点击安装就好了&#xff0c;没什么好多说的。 启用…

刷代码随想录有感(83):贪心算法——最大子数组和

题干&#xff1a; 代码&#xff1a; class Solution { public:int maxSubArray(vector<int>& nums) {int res INT_MIN;int count 0;for(int i 0; i < nums.size(); i){count nums[i];if(count > res) res count;if(count < 0)count 0;}return res;} …

【创作活动】探索 GPT-4o:下一代语言模型的技术革命

&#x1f604; 19年之后由于某些原因断更了三年&#xff0c;23年重新扬帆起航&#xff0c;推出更多优质博文&#xff0c;希望大家多多支持&#xff5e; &#x1f337; 古之立大事者&#xff0c;不惟有超世之才&#xff0c;亦必有坚忍不拔之志 &#x1f390; 个人CSND主页——Mi…

HTTP报文

HTTP报文 报文流 HTTP报文是在HTTP引用程序之间发送的数据块&#xff0c;这些数据块以一种文本形式的元信息开头&#xff0c;这些信息描述了报文的内容和含义&#xff0c;后面跟着可选的数据部分&#xff0c;这些报文在客户端&#xff0c;服务器和代理之间流动。 报文流入源…

前端项目开发,3个HTTP请求工具

这一小节&#xff0c;我们介绍一下前端项目开发中&#xff0c;HTTP请求会用到的3个工具&#xff0c;分别是fetch、axios和js-tool-big-box中的jsonp请求。那么他们都有哪些小区别呢&#xff1f;我们一起来看一下。 目录 1 fetch 2 axios 3 js-tool-big-box 的 jsonp 请求 …

拷贝构造、移动构造、拷贝赋值、移动赋值

最近在学习C的拷贝构造函数时发现一个问题&#xff1a;在函数中返回局部的类对象时&#xff0c;并没有调用拷贝构造函数。针对这个问题&#xff0c;查阅了一些资料&#xff0c;这里记录整理一下。 调用拷贝构造函数的三种情况&#xff1a; ① 用一个类去初始化另一个对象时&a…

【数据结构与算法 | 基础篇 | 队列篇】力扣102, 107

1. 力扣102 : 二叉树的层序遍历 (1). 题 给你二叉树的根节点 root &#xff0c;返回其节点值的 层序遍历 。 &#xff08;即逐层地&#xff0c;从左到右访问所有节点&#xff09;。 示例 1&#xff1a; 输入&#xff1a;root [3,9,20,null,null,15,7] 输出&#xff1a;[[3]…

刷爆leetcode第六期

题目一 用队列实现栈 请你仅使用两个队列实现一个后入先出&#xff08;LIFO&#xff09;的栈&#xff0c;并支持普通栈的全部四种操作&#xff08;push、top、pop 和 empty&#xff09;。 实现 MyStack 类&#xff1a; void push(int x) 将元素 x 压入栈顶。 int pop() 移除…

【漏洞复现】大华智能物联综合管理平台 fastjson远程代码执行漏洞

0x01 产品简介 大华ICC智能物联综合管理平台对技术组件进行模块化和松耦合&#xff0c;将解决方案分层分级&#xff0c;提高面向智慧物联的数据接入与生态合作能力。 0x02 漏洞概述 由于大华智能物联综合管理平台使用了存在漏洞的Fastson组件,未经身份验让的攻击者可利用 /e…

M功能-支付平台(六)

target&#xff1a;离开柬埔寨倒计时-217day 今天突然发现我在csdn居然把我ip属地搞出来了&#xff0c;之前都没注意到&#xff0c;哎 前言 M功能演示版本做到后期(也就是第二周的后面3天)真的很心酸&#xff0c;这边安排的4后端后面都放弃了&#xff0c;觉得做不出来&#…

ARM-V9 RME(Realm Management Extension)系统架构之系统能力的内存隔离和保护

安全之安全(security)博客目录导读 目录 一、内存隔离和保护 1、颗粒PAS过滤Granular PAS filtering 2、Cache的一致性维护 2.1 物理别名点 Point of Physical Aliasing (PoPA) 2.2 加密点 3、内存(DRAM)保护 3.1 内存加密和完整性 3.2 DRAM scrubbing 本博客探讨 RME…

网络编程 —— Http使用httpClient实现页面爬虫

先去找类型的a标签 取出图片所在网址 取出https://desk.3gbizhi.com/deskMV/438.html 搭建Form界面 Http类 public static HttpClient Client { get; } static Http() {HttpClientHandler handler new HttpClientHandler();//处理消息对象//ServerCertificateCustomValidat…

万亿应急国债项目之通信指挥类应急装备多链路聚合通信设备在应急行业中的重要作用

万亿应急国债项目的推出&#xff0c;无疑是我国在应急领域的一次重大举措。在这一宏大蓝图中&#xff0c;通信指挥类应急装备的多链路聚合通信设备显得尤为重要&#xff0c;其在应急行业中所发挥的作用&#xff0c;堪称不可或缺的关键一环。 通信指挥是应急响应中的核心环节&a…

QT C++ 读写mySQL数据库 图片 例子

在上篇文章中描述了怎样搭建读写数据库的环境。 本文更进一步&#xff0c;描述了读写mySQL数据库&#xff0c;字符、整型数字、图片。读写图片相对难点。 数据库的图片字段用BLOB&#xff0c;如果图片较大要用longblob,否则会报错。 另外&#xff0c;读写数据库都使用了短连…

图形学初识--空间变换

文章目录 前言正文矩阵和向量相乘二维变换1、缩放2、旋转3、平移4、齐次坐标下总结 三维变换1、缩放2、平移3、旋转绕X轴旋转&#xff1a;绕Z轴旋转&#xff1a;绕Y轴旋转&#xff1a; 结尾&#xff1a;喜欢的小伙伴可以点点关注赞哦 前言 前面章节补充了一下基本的线性代数中…

前端Vue小兔鲜儿电商项目实战Day02

一、Pinia快速入门 此处见&#xff1a;Vue从入门到实战Day12-CSDN博客 二、创建项目并精细化配置 1. 创建项目 2. src目录调整 ①删除一些初始化的默认文件 清空assets、components、store、views文件夹下的内容&#xff1b; ②修改剩余代码内容 router/index.js import …

华为昇腾310 ATC模型转换工具安装

参考: https://bbs.huaweicloud.com/blogs/393282?utm_source=zhihu&utm_medium=bbs-ex&utm_campaign=other&utm_content=content https://www.hiascend.com/document/detail/zh/canncommercial/601/inferapplicationdev/atctool/atctool_0004.html 1、基本工具…

js知识点之闭包

闭包 什么是闭包 闭包&#xff0c;是 JavaScript 中一个非常重要的知识点&#xff0c;也是我们前端面试中较高几率被问到的知识点之一。 打开《JavaScript 高级程序设计》和《 JavaScript 权威指南》&#xff0c;会发现里面针对闭包的解释各执一词&#xff0c;在网络上搜索关…

23种设计模式之一— — — —装饰模式详细介绍与讲解

装饰模式详细讲解 一、定义二、装饰模式结构核心思想模式角色模式的UML类图应用场景模式优点模式缺点 实例演示图示代码演示运行结果 一、定义 装饰模式&#xff08;别名&#xff1a;包装器&#xff09; 装饰模式&#xff08;Decorator Pattern&#xff09;是结构型的设计模式…

学业辅导导师:文心一言智能体详细介绍和开发

一、前言 本期题目 开发方向&#xff1a;学习成长类 解读&#xff1a; AI技术在学习成长方向的应用正日益增多&#xff0c;本期赛题需围绕该方向开发智能体包括但不限于:作文辅导助手、个性化学习助手、考试助手、各垂类教育内容专家等 二、我的智能体&#xff1a;学业辅导…