Vue 3 中 `ref` 和 `reactive` 的区别是什么?各自的适用场景?

VIP/

在 Vue 3 中,ref 和 reactive 是实现响应式数据的核心 API,它们在数据类型支持、访问方式、底层实现及适用场景上存在显著差异。以下是两者的详细对比及适用场景分析:

核心区别

特性 ref reactive
数据类型支持 所有类型(基本类型如 number/string/boolean,以及对象/数组) 仅对象或数组(如 { count: 0 } 或 [1, 2, 3]
访问方式 在 JavaScript 中需通过 .value 访问或修改值(如 count.value++ 直接访问或修改属性(如 state.count++
模板中使用 自动解包,无需 .value(如 {{ count }} 直接访问属性(如 {{ state.count }}
重新赋值 支持整体替换(如 count.value = 10 不支持直接替换整个对象(如 state = { count: 10 } 会丢失响应性)
底层实现 通过 RefImpl 类包装值,基本类型会包装成对象,对象类型内部调用 reactive 基于 ES6 Proxy 劫持对象,拦截属性的读写、新增、删除操作
响应式追踪 单个独立的引用,依赖收集按 .value 触发 整个对象及其内部属性统一追踪,依赖收集按属性触发

适用场景

ref 的适用场景

  1. 基本类型数据
    • 适用于计数器(如 const count = ref(0))、开关状态(如 const isOpen = ref(false))、输入框文本等独立值。
    • 示例:
      javascript

      1const count = ref(0);
      2function increment() {
      3  count.value++; // 修改值需通过 .value
      4}
      5
  2. 需要整体替换的对象/数组
    • 当需要完全替换一个对象或数组时(如从接口拉取新数据),ref 更灵活。
    • 示例:
      javascript

      1const user = ref({ name: 'Alice', age: 25 });
      2user.value = { name: 'Bob', age: 30 }; // 整体替换保持响应性
      3
  3. 引用 DOM 元素
    • 在模板中通过 ref 属性挂载 DOM 元素,并在 JavaScript 中访问。
    • 示例:
      html

      1<template>
      2  <input ref="inputRef" />
      3</template>
      4<script setup>
      5import { ref, onMounted } from 'vue';
      6const inputRef = ref(null);
      7onMounted(() => {
      8  inputRef.value.focus(); // 访问 DOM 元素
      9});
      10</script>
      11
  4. 组合式函数返回数据
    • 在组合式函数中返回响应式数据时,使用 ref 可以确保解构后仍保持响应性(需配合 toRefs)。
    • 示例:
      javascript

      1function useCounter() {
      2  const count = ref(0);
      3  return { count }; // 返回的 count 保持响应性
      4}
      5

reactive 的适用场景

  1. 复杂对象或嵌套数据结构
    • 适用于表单数据、用户信息、配置对象等关联性强的多字段数据。
    • 示例:
      javascript

      1const form = reactive({
      2  username: '',
      3  password: '',
      4  remember: false
      5});
      6form.username = 'Alice'; // 直接修改属性
      7
  2. 数组操作
    • 对数组的增删改查操作(如 pushpopsplice)天然支持响应式。
    • 示例:
      javascript

      1const todos = reactive(['Learn Vue 3', 'Build a project']);
      2todos.push('Deploy to production'); // 数组操作保持响应性
      3
  3. 深层嵌套对象
    • 对象的嵌套属性也会被自动代理为响应式,无需额外处理。
    • 示例:
      javascript

      1const nestedData = reactive({
      2  user: {
      3    profile: {
      4      name: 'Alice',
      5      address: { city: 'New York' }
      6    }
      7  }
      8});
      9nestedData.user.profile.address.city = 'Beijing'; // 深层修改仍响应式
      10
  4. 模块化状态管理
    • 在大型应用中,可以用 reactive 创建模块化的状态对象,便于维护和扩展。
    • 示例:
      javascript

      1const store = reactive({
      2  user: { name: 'Jane', loggedIn: false },
      3  settings: { theme: 'dark', notifications: true }
      4});
      5function login() {
      6  store.user.loggedIn = true; // 修改嵌套属性
      7}
      8

性能与最佳实践

  • 性能差异ref 和 reactive 的性能差异微小,可忽略不计。ref 对基本类型进行轻量级劫持,对象类型内部调用 reactivereactive 直接通过 Proxy 代理对象。
  • 最佳实践
    • 基本类型用 ref,复杂对象用 reactive
    • 解构 reactive 对象时,使用 toRefs 保持响应性。
    • 避免在 reactive 中嵌套 ref(除非明确需要独立引用)。
    • 对大型数据集考虑 shallowRef 或 shallowReactive 提升性能。

购买须知/免责声明
1.本文部分内容转载自其它媒体,但并不代表本站赞同其观点和对其真实性负责。
2.若您需要商业运营或用于其他商业活动,请您购买正版授权并合法使用。
3.如果本站有侵犯、不妥之处的资源,请在网站右边客服联系我们。将会第一时间解决!
4.本站所有内容均由互联网收集整理、网友上传,仅供大家参考、学习,不存在任何商业目的与商业用途。
5.本站提供的所有资源仅供参考学习使用,版权归原著所有,禁止下载本站资源参与商业和非法行为,请在24小时之内自行删除!
6.不保证任何源码框架的完整性。
7.侵权联系邮箱:aliyun6168@gail.com / aliyun666888@gail.com
8.若您最终确认购买,则视为您100%认同并接受以上所述全部内容。

免费源码网 建站教程 Vue 3 中 `ref` 和 `reactive` 的区别是什么?各自的适用场景? https://svipm.com.cn/21148.html

相关文章

猜你喜欢