Vue3使用Composition API实现响应式

2024-05-30 02:52

本文主要是介绍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组件的渲染过程和响应式系统的运作。

这篇关于Vue3使用Composition API实现响应式的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1015378

相关文章

Java实现检查多个时间段是否有重合

《Java实现检查多个时间段是否有重合》这篇文章主要为大家详细介绍了如何使用Java实现检查多个时间段是否有重合,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录流程概述步骤详解China编程步骤1:定义时间段类步骤2:添加时间段步骤3:检查时间段是否有重合步骤4:输出结果示例代码结语作

Java中String字符串使用避坑指南

《Java中String字符串使用避坑指南》Java中的String字符串是我们日常编程中用得最多的类之一,看似简单的String使用,却隐藏着不少“坑”,如果不注意,可能会导致性能问题、意外的错误容... 目录8个避坑点如下:1. 字符串的不可变性:每次修改都创建新对象2. 使用 == 比较字符串,陷阱满

Python使用国内镜像加速pip安装的方法讲解

《Python使用国内镜像加速pip安装的方法讲解》在Python开发中,pip是一个非常重要的工具,用于安装和管理Python的第三方库,然而,在国内使用pip安装依赖时,往往会因为网络问题而导致速... 目录一、pip 工具简介1. 什么是 pip?2. 什么是 -i 参数?二、国内镜像源的选择三、如何

使用C++实现链表元素的反转

《使用C++实现链表元素的反转》反转链表是链表操作中一个经典的问题,也是面试中常见的考题,本文将从思路到实现一步步地讲解如何实现链表的反转,帮助初学者理解这一操作,我们将使用C++代码演示具体实现,同... 目录问题定义思路分析代码实现带头节点的链表代码讲解其他实现方式时间和空间复杂度分析总结问题定义给定

Linux使用nload监控网络流量的方法

《Linux使用nload监控网络流量的方法》Linux中的nload命令是一个用于实时监控网络流量的工具,它提供了传入和传出流量的可视化表示,帮助用户一目了然地了解网络活动,本文给大家介绍了Linu... 目录简介安装示例用法基础用法指定网络接口限制显示特定流量类型指定刷新率设置流量速率的显示单位监控多个

Java覆盖第三方jar包中的某一个类的实现方法

《Java覆盖第三方jar包中的某一个类的实现方法》在我们日常的开发中,经常需要使用第三方的jar包,有时候我们会发现第三方的jar包中的某一个类有问题,或者我们需要定制化修改其中的逻辑,那么应该如何... 目录一、需求描述二、示例描述三、操作步骤四、验证结果五、实现原理一、需求描述需求描述如下:需要在

部署Vue项目到服务器后404错误的原因及解决方案

《部署Vue项目到服务器后404错误的原因及解决方案》文章介绍了Vue项目部署步骤以及404错误的解决方案,部署步骤包括构建项目、上传文件、配置Web服务器、重启Nginx和访问域名,404错误通常是... 目录一、vue项目部署步骤二、404错误原因及解决方案错误场景原因分析解决方案一、Vue项目部署步骤

JavaScript中的reduce方法执行过程、使用场景及进阶用法

《JavaScript中的reduce方法执行过程、使用场景及进阶用法》:本文主要介绍JavaScript中的reduce方法执行过程、使用场景及进阶用法的相关资料,reduce是JavaScri... 目录1. 什么是reduce2. reduce语法2.1 语法2.2 参数说明3. reduce执行过程

如何使用Java实现请求deepseek

《如何使用Java实现请求deepseek》这篇文章主要为大家详细介绍了如何使用Java实现请求deepseek功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1.deepseek的api创建2.Java实现请求deepseek2.1 pom文件2.2 json转化文件2.2

Java调用DeepSeek API的最佳实践及详细代码示例

《Java调用DeepSeekAPI的最佳实践及详细代码示例》:本文主要介绍如何使用Java调用DeepSeekAPI,包括获取API密钥、添加HTTP客户端依赖、创建HTTP请求、处理响应、... 目录1. 获取API密钥2. 添加HTTP客户端依赖3. 创建HTTP请求4. 处理响应5. 错误处理6.