Vue3获取响应式数据的四种方法
作者:清灵xmf
1. reactive:响应式对象
1、概念
reactive 是用于创建响应式对象的 API。它接收一个普通对象并返回一个代理对象。
这个代理对象是深度响应的,也就是说,该对象及其所有嵌套对象都会成为响应式的。并且可以感知到对它的所有操作(如属性的读写、删除等),并在数据变化时自动触发视图更新。
2、用法
import { reactive } from 'vue' const reactiveObj = reactive({ count: 1, flower: { name: 'rose' } }) window.reactiveObj = reactiveObj;
可以在控制台输出 reactiveObj 查看,也可以修改它的数据。
3、特性
1)深度响应式:reactive 会递归地将对象及其所有嵌套对象转化为响应式对象。
2)Proxy 机制:reactive 基于 Proxy 实现,比 Vue 2 中的 Object.defineProperty 更加灵活和高效。
3)自动依赖追踪:当响应式对象的属性在模板或计算属性中被引用时,Vue 会自动追踪这些依赖,并在数据变化时更新相关的视图。
4、注意
浅拷贝问题:reactive 创建的对象是一个代理对象,如果直接替换该对象(如 reactiveObj = {}),将无法保持响应式效果。因此,建议修改对象的属性,而不是替换整个对象来保持响应式。
<template> <div> <p>reactiveObj.count: {{ reactiveObj.count }}</p> </div> </template> <script setup> import { reactive } from 'vue'; const reactiveObj = reactive({ count: 1 }) window.reactiveObj = reactiveObj; </script>
2. ref:响应式引用
1、概念
ref 是另一种创建响应式数据的方法,特别适用于基本类型的值(如字符串、数字、布尔值等),或需要独立的响应式引用。
ref 会返回一个包含 .value 属性的对象,这个属性持有实际值,并且是响应式的。
2、用法
import { ref, reactive } from "vue"; // value 是普通类型数据时 const numberRef = ref(0); window.numberRef = numberRef; const stringRef = ref("hello"); window.stringRef = stringRef; // value 是一个对象时 const objectRef = ref({ a: 1, b: 2 }); window.objectRef = objectRef; // value 是一个代理对象 const reactiveObj = reactive({ a: 11, b: 22 }); const reactiveRef = ref(reactiveObj); window.reactiveObj = reactiveObj; window.reactiveRef = reactiveRef;
3、特性
1)单值响应式:ref 非常适合处理基本数据类型的响应式数据,或者是希望一个对象保持独立响应时。
2)模板自动解包:在模板中使用 ref 时,Vue 会自动解包 .value,不需要显式使用 .value。
<template> <div>{{ numberRef }}</div> <!-- Vue 自动解包为 numberRef.value --> </template>
3)组合式 API 的灵活性:ref 在组合式 API 中非常灵活,适合管理组件内部的状态和独立的响应式变量。
4、总结
1)传入一个普通数据时,返回一个对象,对象属性 value 是响应式数据。
2)传入一个对象时,会调用一下 reactive,将该对象变成一个代理 proxy,目的是为了让对象里面的所有属性全部变成响应式数据。
3)传入一个代理对象时,返回代理对象本身。
3. readonly:只读响应式对象
1、概念
readonly 是 Vue 3 提供的用于创建只读响应式对象的 API。它接收一个响应式对象或普通对象,并返回一个只读代理对象。
这个对象的所有属性都变为只读,任何尝试修改它的操作都会在开发环境下触发警告。
2、用法
readonly 通常用于保护一些不应被直接修改的数据,例如共享状态或常量数据。
import { reactive, readonly } from "vue"; const reactiveObj = reactive({ a: 1, b: 2 }); const readonlyObj1 = readonly({ a: 11, b: 22 }); const readonlyObj2 = readonly(reactiveObj); window.reactiveObj = reactiveObj; window.readonlyObj1 = readonlyObj1; window.readonlyObj2 = readonlyObj2;
4. computed:计算属性
1、概念
computed 是 Vue 3 提供的用于创建计算属性的 API。计算属性基于响应式数据或其他计算属性,它们的值是通过一个函数计算出来的,并且只有当其依赖的响应式数据发生变化时,计算属性才会重新计算。这使得计算属性在性能和代码简洁性上具有很大优势。
2、用法
computed 接收一个函数,这个函数返回的值会被 Vue 缓存,直到依赖的响应式数据发生变化时,才会重新计算。
import { computed, reactive } from "vue"; const reactiveObj = reactive({ a: 1, b: 2 }); const sumRef = computed(() => { console.log("computed函数执行"); return reactiveObj.a + reactiveObj.b; }); console.log(sumRef); console.log(sumRef.value); console.log(sumRef.value); console.log(sumRef.value); reactiveObj.a = 3; reactiveObj.b = 4; console.log(sumRef.value); console.log(sumRef.value);
3、特性
1)缓存机制:computed 的值是惰性计算的,并且会被缓存,直到依赖项变化。这与方法不同,方法在每次调用时都会执行,而计算属性只有在依赖变化时才会重新计算。
2)只读默认性:计算属性默认是只读的,但也可以通过传递一个带有 get 和 set 的对象,使其成为可写的计算属性。
import { ref, computed } from 'vue' const count = ref(1); const double = computed({ get: () => count.value * 2, set: (value) => { count.value = value / 2 } }) double.value = 10; console.log(count.value) // 5 count.value = 20; console.log(double.value); // 40
4、注意
1)避免副作用:computed 应该始终是纯函数,不应包含会产生副作用的代码(例如,网络请求、DOM 操作等),这部分逻辑应放在 watch 或方法中处理。
2)适度使用:虽然计算属性很强大,但在一些场景下,使用方法或 watch 可能会更加合适。
以上就是Vue3获取响应式数据的四种方法的详细内容,更多关于Vue3获取响应式数据的资料请关注脚本之家其它相关文章!