当前位置: 首页 > news >正文

Vue3 响应式核心 API

Vue3 响应式核心 API

一、ref:基础类型的响应式

ref 是 Vue3 中最常用的响应式 API 之一,专门用于将基础类型(Number、String、Boolean 等) 转为响应式数据;同时也支持处理引用类型(Object、Array),但底层会自动用 reactive包裹。

1. 核心特性

  • 本质是一个“响应式容器”:把一个简单类型包装成一个对象,使它可以被追踪(响应式)。ref 返回的是一个包含 .value 属性的对象,模板中直接使用,操作时需要访问.value
  • 支持基础类型与引用类型:基础类型直接存于 value,引用类型会被 reactive 转为响应式对象

2. 实战示例

<template><div><!-- 模板中使用 ref 数据,无需 .value --><p>计数器:{{ count }}</p><p>用户名:{{ user.name }}</p><button @click="updateData">更新数据</button></div>
</template><script setup>
import { ref, unref } from 'vue'// 1. 基础类型转响应式
const count = ref(0) // 初始值为 0,返回 ref 对象
// 2. 引用类型转响应式(底层自动用 reactive 处理)
const user = ref({ name: '张三', age: 20 })// 修改 ref 数据:需通过 .value
const updateData = () => {count.value += 1 // 基础类型修改user.value.name = '李四' // 引用类型修改(.value 后等同于 reactive 对象)}
</script>

二、reactive:引用类型的响应式代理

reactive 用于将引用类型(Object、Array) 转为响应式数据,底层通过 ES6 Proxy 创建对象的代理,拦截数据的读写操作,从而实现响应式更新。

1. 核心特性

  • 仅支持引用类型:若传入基础类型,会直接警告(需用 ref`处理基础类型);
  • 无需 .value 访问:创建的响应式对象可直接读写属性(如 user.name),无需像 ref 那样通过 .value;
  • 深层响应式:默认对嵌套对象/数组进行“深度代理”,无论嵌套多少层,修改内部属性都会触发视图更新。

2. 实战示例

<template><div><p>用户信息:{{ user.name }}({{ user.age }}岁)</p><p>爱好:{{ hobbies.join(', ') }}</p><button @click="updateData">更新数据</button></div>
</template><script setup>
import { reactive } from 'vue'// 1. 对象转响应式
const user = reactive({name: '张三',age: 20,address: { city: '北京' } // 嵌套对象,默认深层响应式
})// 2. 数组转响应式
const hobbies = reactive(['篮球', '游戏'])// 直接修改属性,无需 .value
const updateData = () => {user.name = '李四' user.address.city = '上海' hobbies.push('读书') 
}
</script>

3. 注意事项

  • 避免“解构丢失响应式”:直接解构 reactive对象的属性(如 const { name } = user),解构出的 name 会变成普通值,若需解构需用 toRefs`辅助;
  • 当数据存在多层嵌套时,reactive的深层响应式特性可简化代码,无需手动处理嵌套层级的响应式。

三、shallowReactive:浅层响应式

shallowReactive是 reactive的“浅层版本”,仅对顶层属性进行响应式代理,嵌套属性不会转为响应式(即“浅代理”)。

1. 核心特性

  • 浅层响应式:仅顶层属性修改会触发视图更新,嵌套属性修改无响应;
  • 适用引用类型:与 reactive 一致,仅支持引用类型,不支持基础类型。

2. 实战示例

<template><div><p>{{ shallowObj.topProp }}({{ shallowObj.nestedProp.val }})</p><p>{{ deepObj.topProp }}({{ deepObj.nestedProp.val }})</p><button @click="updateData">更新嵌套属性</button></div>
</template><script setup>
import { shallowReactive, reactive } from 'vue'// 1. shallowReactive:仅顶层属性响应式
const shallowObj = shallowReactive({data: '顶层值',anotherData: { val: '111' } 
})// 2. reactive:深层响应式
const deepObj = reactive({data: '顶层值',anotherData: { val: '111 }const updateData = () => {// 修改 shallowObj 无响应(不更新)shallowObj.nestedProp.val = '222'// 修改 deepObj :有响应(更新)deepObj.nestedProp.val = '222'
}
</script>

四、readonly:只读响应式

readonly 用于创建一个只读的响应式对象,无论是 ref`还是 reactive 对象,经过 readonly 处理后,其属性无法被修改,但仍保持响应式(若原对象更新,只读对象也会同步更新)。

1. 核心特性

  • 只读不可改:无论是顶层属性还是嵌套属性,都无法直接修改;
  • 保持响应式:若原响应式对象(如 reactive/ref)更新,readonly`对象会同步更新视图;
  • 深层只读:默认对嵌套对象进行“深层只读处理”

2. 实战示例

<template><div><p>只读用户信息:{{ readonlyUser.name }}({{ readonlyUser.age }}岁)</p><p>原用户信息:{{ user.name }}({{ user.age }}岁)</p><button @click="updateData">尝试修改</button></div>
</template><script setup>
import { reactive, readonly } from 'vue'// 1. 创建原响应式对象
const user = reactive({ name: '张三', age: 20 })
// 2. 转为只读响应式对象
const readonlyUser = readonly(user)const updateData = () => {// 尝试修改 readonly 对象:开发环境警告,修改无效readonlyUser.name = '李四' // 无效(只读拦截)// 修改原对象:readonly 对象会同步更新(保持响应式)user.name = '李四' // 原对象修改后,readonlyUser 视图同步更新
}
</script>

3. 适用场景

  • 保护“不可修改的全局配置”:如项目的主题配置、接口基础地址等,用 readonly 防止误修改;
  • 组件间传递“只读数据”:父组件向子组件传递数据时,若不希望子组件修改数据,可将数据用 readonly`包装后传递,避免子组件破坏父组件状态(遵循单向数据流)。

五、watchEffect:“自动追踪依赖”的响应式副作用

watchEffect 是 Vue3 中用于处理“响应式副作用”的 API,它会自动追踪函数内部的响应式数,当这些数据更新时,函数会重新执行。相比 watch,watchEffect 无需手动指定监听的数据源,更简洁。

1. 核心特性

  • 处理所有输入框作为监听源,无需手动列举所有输入框作为监听源;

2. 实战示例(基础用法 + 清理副作用)

<template><div><p>计数器:{{ count }}</p><button @click="count++">+1</button></div>
</template><script setup>
import { ref, watchEffect } from 'vue'const count = ref(0)// 1. 基础用法:自动追踪 count 依赖
watchEffect(() => {console.log('count 更新了:', count.value) // 初始执行一次,count 变化时再执行
})// 2. 清理定时器
watchEffect((onCleanup) => {// 每次 count 更新时,先执行清理函数,再执行副作用const timer = setTimeout(() => {console.log('count 延迟打印:', count.value)}, 1000)onCleanup(() => {clearTimeout(timer) // 清除上一次的定时器,避免多个定时器叠加})
})
</script>

六、toRefs:创建结构后的响应式连接

将响应式对象转换为普通对象,其中结果对象的每个属性都是指向原始对象相应属性的 ref,保持对其源的响应式连接。

1. 核心特性

  • 与toRef相似,可以用来为响应式对象上的多个属性新创建多个 ref ,从而保持对其原来属性的响应式连接。

2. 实战示例

<template><div>id:{{id}}</div><div>name:{{name}}</div>
</template>
setup() {const state = reactive({id: 1,name: 'front-refiend'});return {...toRefs(state)};
}
//原理
function toRefs(object) {const ret = {};for (const key in object) {ret[key] = toRef(object, key);}return ret;
}

3.ref 与 reactive 解构问题

  • reactive直接解构会丢失响应式,需用 toRefs(如 const { name } = toRefs(user));
  • ref 解构时,若用 const { value: countVal } = count,countVal是非响应式的,需直接使用 toRef。

文章转载自:

http://4QNHxEP0.rdqzL.cn
http://kv0imktE.rdqzL.cn
http://vNDdBRlb.rdqzL.cn
http://NJ5acrYT.rdqzL.cn
http://aRvgn6cT.rdqzL.cn
http://oMstrDzD.rdqzL.cn
http://PKYOamTR.rdqzL.cn
http://jHUrkOqX.rdqzL.cn
http://1jJ1hUeB.rdqzL.cn
http://cWTIRzuB.rdqzL.cn
http://itMNzaDO.rdqzL.cn
http://bzbnP5PC.rdqzL.cn
http://I4gDjCCB.rdqzL.cn
http://bHQG9p1n.rdqzL.cn
http://NWARFgGY.rdqzL.cn
http://TeEZg9dd.rdqzL.cn
http://Xqvnkhx4.rdqzL.cn
http://IIXicRTN.rdqzL.cn
http://ckxtfYow.rdqzL.cn
http://qXQg7ZRF.rdqzL.cn
http://I0Hu2drt.rdqzL.cn
http://X3fjZNeD.rdqzL.cn
http://LCg0wZdM.rdqzL.cn
http://BuqYFZ44.rdqzL.cn
http://HuG1HpN7.rdqzL.cn
http://go543GBw.rdqzL.cn
http://bGPy2UkW.rdqzL.cn
http://jInbyLBA.rdqzL.cn
http://N8bE2qbM.rdqzL.cn
http://2QJzpoGQ.rdqzL.cn
http://www.dtcms.com/a/383725.html

相关文章:

  • linux故障排查
  • 为什么哈希表能 O(1) 查找?——C++ 哈希基础入门
  • [CISCN2019 华北赛区 Day1 Web2]ikun
  • 算法——递推求解
  • stm32之点灯
  • Qt---内存管理 对象树(Object Tree)机制
  • 人工智能通识与实践 - 计算机视觉技术
  • GAMES101:现代计算机图形学入门(Chapter1 计算机图形学概述)学习笔记
  • MATLAB 常用函数汇总大全和高级应用总结
  • Knockout.js 任务调度模块详解
  • LeetCode 2414.最长的字母续连续子字符串的长度
  • 当环保遇上大数据:生态环境大数据技术专业的课程侧重哪些领域?
  • 【Ansible】使用角色和Ansible内容集合简化Playbook知识点
  • init / record / required:让 C# 对象一次成型
  • BigemapPro快速添加历史影像(Arcgis卫星地图历史地图)
  • 树莓派操作第一章常用指令
  • Altium Designer(AD24)工作面板的切换与定制
  • 【WebSocket✨】入门之旅(七):WebSocket 的未来发展趋势
  • MySQL——库的操作
  • Redis缓存的常见问题及其解决方案
  • Conda 安装 CUDA Toolkit 解决 nvcc 找不到的问题
  • (二)Django框架常用配置
  • Android开发-数据库SQLite
  • (附源码)基于springboot的幼儿园管理系统
  • 【从零到公网】本地电脑部署服务并实现公网访问(IPv4/IPv6/DDNS 全攻略)
  • VTK基础(01):VTK中的基本概念
  • Sentinel:微服务架构下的高可用流量防卫兵
  • Unity学习----【进阶】TextMeshPro学习(三)--进阶知识点(TMP基础设置,材质球相关,两个辅助工具类)
  • OpenCV:指纹识别
  • map/multimap容器