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实现响应式的更多相关文章
- vue3.0 composition API
一.Setup函数 1.创建时间:组件创建之前被调用,优先与created被调用,this指向的实例为window,created所指向的实例为proxy 2.this指向:不会指向组件实例 3.参数 ...
- 好久没发文了,一篇Vue3的Composition API使用奉上
Composition API Composition API是Vue3中推荐的组件代码书写方式,相较于传统的Options API来说,它能让业务逻辑处理和后期代码维护变的更加简单. 首先我们来看O ...
- 学习 vue3 第一天 vue3简介,创建vue3项目 Composition Api 初识
前言: 从今天开始来和大家一起学习 vue3 相信大家都不陌生,已经火了一段时间了,但是还是有不少人没有学习,那就跟着六扇老师来简单的入个门 废话不多说,来开始今天的学习 Vue3 简介: 2020年 ...
- vue3 学习笔记 (五)——vue3 的 setup 如何实现响应式功能?
setup 是用来写组合式 api ,内部的数据和方法需要通过 return 之后,模板才能使用.在之前 vue2 中,data 返回的数据,可以直接进行双向绑定使用,如果我们把 setup 中数据类 ...
- 基于 Vue3.0 Composition Api 快速构建实战项目
Quick Start 项目源码:https://github.com/Wscats/vue-cli 本项目综合运用了 Vue3.0 的新特性,适合新手学习
- Vue3中的响应式api
一.setup文件的认识 特点1:script 中间的内容就是一个对象 特点2:script 在第一层 定义的方法 或者 变量 => 就是这个对象 属性 => 顶层的绑定回被暴露给模板( ...
- Vue3的新特性及相关的Composition API使用
首先 创建项目 Vue3 Vue3 相较于Vue2 的6大亮点: 1 性能快. 2 按需编译 体积更小 3 提供了组合API 类似于react 的React Hooks 4 更好的Ts支持 5 暴露了 ...
- mixin和composition api
1. 这两个都是实现组件逻辑复用的法宝 2. composition api是vue3的, composition api的出现就是解决mixins的不足之处的 一. mixin 回顾下mixin, ...
- iOS响应式编程:ReactiveCocoa vs RxSwift 选谁好
转载: iOS响应式编程:ReactiveCocoa vs RxSwift 选谁好 内容来自stack overflow的一个回答:ReactiveCocoa vs RxSwift – pros an ...
- 【Vue源码学习】响应式原理探秘
最近准备开启Vue的源码学习,并且每一个Vue的重要知识点都会记录下来.我们知道Vue的核心理念是数据驱动视图,所有操作都只需要在数据层做处理,不必关心视图层的操作.这里先来学习Vue的响应式原理,V ...
随机推荐
- 史上最全的中高级JAVA工程师-面试题汇总
史上最全的中高级JAVA工程师-面试题汇总 置顶 2019-10-15 18:58:32 Jeff.Smile 阅读数 34460更多 分类专栏: # 随笔 版权声明:本文为博主原创文章,遵循CC 4 ...
- 国产gowin开发板GW1NR-9K的PSRAM使用说明
开发板子采用GW1NNR-LV9LQ144PC6/I5 FPGA器件.具有低功耗,瞬时启动,高安全性,低成本,方便扩展等特点.本开发板价格价格便宜,板子扩张性容易,帮助用户比较快速进入国产FPGA学习 ...
- CentOS+Django+uWSGI+Celery+Supervisor配置
目录 背景 目录 安装 配置Supervisor 1.生成配置文件 2. 修改配置文件 3. 创建进程文件 创建 uwsgi.conf 进程文件 创建celery进程文件 启动supervisor 启 ...
- Go 单元测试之mock接口测试
目录 一.gomock 工具介绍 二.安装 三.使用 3.1 指定三个参数 3.2 使用命令为接口生成 mock 实现 3.3 使用make 命令封装处理mock 四.接口单元测试步骤 三.小黄书Se ...
- css3新单位vw、vh、vmin、vmax的使用详解
1,vw.vh.vmin.vmax 的含义 (1) vw. vh. vmin. vmax 是一种视窗单位,也是相对单位.它相对的不是父节点或者页面的根节点.而是由视窗( Viewport)大小来决定的 ...
- 聊聊从大模型来看NLP解决方案之UIE
转载请备注出处:https://www.cnblogs.com/zhiyong-ITNote 概述 自然语言处理NLP任务的实现,相比较以前基于传统机器学习算法实现方法,现在越来越集中使用大模型来实现 ...
- 牛客网-SQL专项训练24
①下列选项关于游标的作用叙述正确的是(D) 解析: 游标是一种从包括多条数据记录的结果集中每次提取一条记录以便处理的机制,可以看做是查询结果的记录指针.游标与视图类似,也是基于基表的临时表对象,也能够 ...
- HarmonyOS NEXT应用开发案例——列表编辑实现
介绍 本示例介绍用过使用ListItem组件属性swipeAction实现列表左滑编辑效果的功能. 该场景多用于待办事项管理.文件管理.备忘录的记录管理等. 效果图预览 使用说明: 点击添加按钮,选择 ...
- 解析 RocketMQ 业务消息——“事务消息”
简介: 本篇文章通过拆解 RocketMQ 事务消息的使用场景.基本原理.实现细节和实战使用,帮助大家更好的理解和使用 RocketMQ 的事务消息. 作者:合伯 引言:在分布式系统调用场景中存在 ...
- 一文理解 K8s 容器网络虚拟化
简介:本文需要读者熟悉 Ethernet(以太网)的基本原理和 Linux 系统的基本网络命令,以及 TCP/IP 协议族并了解传统的网络模型和协议包的流转原理.文中涉及到 Linux 内核的具体实现 ...