Vue3的ref与reactive

embedded/2025/2/27 23:00:24/

为什么推荐使用ref而不是reactive
reactive在使用过程中存在一些局限性,如果不额外注意这些问题,可能会给开发带来一些不便。与此不同,ref
更像是Vue2时代的option API中的data的替代品,可以存放任何数据类型,而reactive声明的数据类型则仅限于对象。
总体来说,非必要的情况下最好避免使用reactive。官方文档也强烈推荐使用ref()
作为声明响应式状态的主要API。以下是详细原因:

  1. 局限性问题: reactive本身存在一些局限性,可能会在开发过程中引发一些问题。这需要额外的注意力和处理,否则可能对开发造成麻烦。
  2. 数据类型限制: reactive声明的数据类型仅限于对象,而ref则更加灵活,可以容纳任何数据类型。这使得ref更适合一般的响应式状态的声明。
  3. 官方推荐: 官方文档强烈建议使用ref()作为声明响应式状态的首选。这是因为ref更简单、更直观,同时避免了reactive可能引发的一些问题。
    总的来说:除非有特定的需求需要使用reactive,否则在大多数情况下更推荐使用ref()
    在这里插入图片描述

reactive和 ref对比
在这里插入图片描述

即:

  • ref用于将基本类型的数据和引用数据类型(对象)转换为响应式数据,通过 .value
    访问和修改。
  • reactive用于将对象转换为响应式数据,可以直接访问和修改属性,适用于复杂的嵌套对象和数组。
    01: reactive有限的值类型
    reactive只能声明引用数据类型(对象)
    let obj = reactive({
    name: ‘小明’,
    age: 18
    })
    ref既能声明基本数据类型,也能声明对象和数组
    Vue 提供了 ref()方法,允许我们创建可以使用任何值类型的响应式 ref

    // 对象
    const state = ref({})
    // 数组
    const state2 = ref([])
    使用 ref,你可以灵活地声明基本数据类型、对象或数组,而不受像 reactive那样只能处理引用数据类型的限制。这为开发提供了更大的灵活性,尤其是在处理不同类型的数据时。
    02: reactive使用不当会失去响应
    使用 reactive时,如果不当使用,可能导致响应性失效,带来一些困扰。这可能让开发者在愉快编码的同时,突然发现某些操作失去了响应性,不明所以。因此,建议在不了解 reactive失去响应的情况下慎用,而更推荐使用 ref
  1. 赋值给 reactive一个整个对象或 reactive对象
    赋值一个普通对象
    let state = reactive({ count: 0 })
    // 这个赋值将导致 state 失去响应
    state = { count: 1 }
    赋值一个 reactive对象

    {{ state }}

在 nextTick中给 state赋值一个 reactive的响应式对象,但是 DOM 并没有更新。
解决方法:

  1. 不要直接整个对象替换,一个个属性赋值
    let state = reactive({ count: 0 })
    // state = { count: 1 }
    state.count = 1
  2. 使用 Object.assign
    let state = reactive({ count: 0 })
    // state = { count: 1 },state 不会失去响应
    state = Object.assign(state, { count: 1 })
  3. 使用 ref定义对象
    let state = ref({ count: 0 })
    state.value = { count: 1 }
  4. 将 reactive对象的属性赋值给变量(断开连接/深拷贝)
    这种操作类似于深拷贝,不再共享同一内存地址,而是只是字面量的赋值,对该变量的赋值不会影响原来对象的属性值。
    let state = reactive({ count: 0 })
    // 赋值给 n,n 和 state.count 不再共享响应性连接
    let n = state.count
    // 不影响原始的 state
    n++
    console.log(state.count) // 0
    解决方案:
  • 避免将 reactive对象的属性赋值给变量。
  1. 直接 reactive对象解构时
    直接解构会失去响应。
    let state = reactive({ count: 0 })
    // 普通解构,count 和 state.count 失去了响应性连接
    let { count } = state
    count++ // state.count 值依旧是 0
    解决方案:
    使用 toRefs解构,解构后的属性是 ref的响应式变量。
    const state = reactive({ count: 0 })
    // 使用 toRefs 解构,后的属性为 ref 的响应式变量
    let { count } = toRefs(state)
    count.value++ // state.count 值改变为 1
    建议:ref一把梭
    推荐使用 ref,总结原因如下:

  2. reactive有限的值类型:只能声明引用数据类型(对象/数组)。

  3. reactive在一些情况下会失去响应,这可能导致数据回显失去响应(数据改了,DOM 没更新)。

    {{ state.a }}
    {{ state.b }}
    {{ state.c }}

上面这个例子如果是使用 ref进行声明,直接赋值即可,不需要将属性拆分一个个赋值。使用 ref
替代 reactive:

{{ state.a }}
{{ state.b }}
{{ state.c }}

  • 给响应式对象的字面量赋一整个普通对象或 reactive对象将导致 reactive声明的响应式数据失去响应。
  1. ref适用范围更广,可声明基本数据类型和引用数据类型。
    虽然使用 ref声明的变量在读取和修改时都需要加 .value小尾巴,但正因为有这个小尾巴,我们在 review 代码的时候就很清楚知道这是一个 ref声明的响应式数据。

ref的 .value好麻烦!
ref声明的响应式变量携带迷人的 .value小尾巴,让我们一眼就能确定它是一个响应式变量。虽然使用 ref
声明的变量在读取和修改时都需要加 .value小尾巴,但是正因为有这个小尾巴,我们在 review 代码的时候就很清楚知道这是一个 ref声明的响应式数据。可能有些人不喜欢这个迷人小尾巴,如果我能自动补全,阁下又如何应对?
Volar 插件能自动补全 .value
推荐 ref一把梭,但是 ref又得到处 .value,那就交给插件来完成吧!

  • Volar自动补全 .value(不是默认开启,需要手动开启)
    reactive
    重新赋值丢失响应是因为引用地址变了,被 proxy
    代理的对象已经不是原来的那个,所以丢失响应了。其实 ref
    也是一样的,当把 .value
    那一层替换成另外一个有着 .value
    的对象也会丢失响应。ref
    定义的属性等价于 reactive({ value: xxx })

    另外,说使用 Object.assign
    为什么可以更新模板:
    Object.assign
    解释是这样的:如果目标对象与源对象具有相同的键(属性名),则目标对象中的属性将被源对象中的属性覆盖,后面的源对象的属性将类似地覆盖前面的源对象的同名属性。
    那个解决方法里不用重新赋值,直接 Object.assign(state, { count: 1 })
    即可,所以只要 proxy
    代理的引用地址没变,就会一直存在响应性

GPT对reactive的回答:
[图片]

[图片]

[图片]


http://www.ppmy.cn/embedded/167652.html

相关文章

AI人工智能机器学习之监督线性模型

1、概要 本篇学习AI人工智能机器监督学习框架下的线性模型,以LinearRegression线性回归和LogisticRegression逻辑回归为示例,从代码层面测试和讲述监督学习中的线性模型。 2、监督学习之线性模型 - 简介 监督学习和线性模型是的两个重要概念。 监督学…

Lumoz Chain正式上线:AI 时代的新算力破局者

新的叙事和技术突破永远是推动行业前行的核心动力。当下,AI Agent无疑是最炙手可热的赛道之一。 当加密世界将目光投向AI领域时,大多数项目仍停留在以AI为工具或应用场景的层面,试图通过集成AI模型或优化链上功能来吸引用户。然而&#xff0c…

从零到一:如何用阿里云百炼和火山引擎搭建专属 AI 助手(DeepSeek)?

本文首发:从零到一:如何用阿里云百炼和火山引擎搭建专属 AI 助手(DeepSeek)? 阿里云百炼和火山引擎都推出了免费的 DeepSeek 模型体验额度,今天我和大家一起搭建一个本地的专属 AI 助手。  阿里云百炼为 …

【量化-什么是信息?怎么有效的学习?关键字摘取】

到底什么是信息呢?我们怎么衡量信息的价值与多少呢?今天,我们就来说说这个问题。 怎么量化信息? 信息,只有量化了才能被准确地讨论,而量化的方法就和事件发生的概率密切相关。或者说得直白一些&#xff0…

Linux设备驱动开发-UART驱动

UART 有三条线,分别是 Rx,Tx 和 GND 数据发送接收步骤: 1.双方约定波特率 2.拉低(从高电平) Tx 引脚维持 1bit 时间 3.接收端在低电平开始处计时 4.发送端根据数据驱动 Tx 引脚电平 5.接收端 1.5bit 时间后读取引…

《AI赋能星际探索:机器人如何开启宇宙新征程!》

在人类对宇宙无尽的探索中,空间探索任务始终充满挑战。从遥远星球的探测,到空间站的维护,每一项任务都需要高精度、高可靠性的操作。人工智能(AI)的迅猛发展,为空间探索机器人带来了革命性的变革&#xff0…

如何在Ubuntu 22.04或20.04 Linux上安装MobaXterm

MobaXterm是一款流行的跨平台终端模拟器,集成了SSH、SFTP等多种网络工具,非常适合远程管理Linux服务器。然而,需要注意的是,MobaXterm本身是一款面向Windows的操作系统软件,没有官方的Linux版本。因此,在Ub…

Jquery详解

一.Jquery介绍 1.jQuery 是一个快速、简洁的 JavaScript 库,它极大地简化了 HTML 文档遍历、事件处理、动画效果和 AJAX 交互等操作,使开发者能够更轻松地创建动态和交互性强的网页。对原生js的封装,提供了很多时间,调用Api即可,并且对浏览器做了兼容性…