Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >[Vue 3] 为什么需要同时使用Ref和Reactive

[Vue 3] 为什么需要同时使用Ref和Reactive

作者头像
前端小智@大迁世界
发布于 2023-08-16 00:25:47
发布于 2023-08-16 00:25:47
45200
代码可运行
举报
文章被收录于专栏:终身学习者终身学习者
运行总次数:0
代码可运行

在使用 Options API 工作时声明响应性数据是直截了当的。data 选项内的所有内容都会自动变为响应性,并在模板中可用。唯一需要注意的是,要将data设为一个函数,以防止在所有组件实例之间共享状态。

让我们讨论一下Vue 3中发生了什么变化,以及为什么我们需要两个不同的助手。

Vue 2中的响应性

data 组件选项内的每个属性都将通过 Object.defineProperty 转换为getter/setter。这些getter/setter对我们来说是看不见的,但在底层,它们使Vue在访问或修改属性时能够执行依赖跟踪。

每个组件都有一个关联的观察者,用于跟踪在组件的渲染周期中使用的属性。如果依赖项更新,观察者会通知组件,然后触发重新渲染。

Vue 3中的响应性

在 Vue 3 中,一切都发生了变化。核心部分从零开始重写,现在由Javascript Proxies提供响应性。Proxies是一种现代且优雅的方式来观察一个对象并在其属性被访问或更新时得到通知。

可以通过以下简单的例子来理解代理是如何工作的:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
const userInfo = {
  firstName: "fotis",
  age: 35,
};

const handler = {
  get(target, property) {
    if (property === "firstName") {
      const name = target[property]
      return name.charAt(0).toUpperCase() + name.slice(1);
    }
    if (property === "age") {
      return '--'
    }
    return target[property]
  },
};

const proxy = new Proxy(userInfo, handler);

console.log(proxy.firstName) // "Fotis"
console.log(proxy.age) // "--"

处理器内部的get方法被称为陷阱,每次访问对象的属性时都会被调用。以类似的方式,可以定义一个设定的陷阱:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
const userInfo = {
  firstName: "Fotis",
  age: 35,
};

const handler = {
  set(target, prop, value) {
    if (prop === "age") {
      if (!Number.isInteger(value)) {
        throw new TypeError("The age is not an integer");
      }
      if (value > 200) {
        throw new RangeError("The age seems invalid");
      }
    }
    target[prop] = value;
    return true;
  },
};

const proxy = new Proxy(userInfo, handler);

proxy.age = 12 // OK
proxy.age = 300 // Error: The age seems invalid

这正是 Vue 3 响应性背后的理念。当使用 reactive 助手声明一个变量时,会使用一个 proxy. 来跟踪任何变化。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
function reactive(obj) {
  return new Proxy(obj, {
    get(target, key) {
      track(target, key)
      return target[key]
    },
    set(target, key, value) {
      target[key] = value
      trigger(target, key)
    }
  })
}

当然,响应式助手的实际实现更为复杂,能处理边缘情况,但其核心仍然使用proxy。

以上的片段解释了为什么将响应性变量解构或重新分配给本地变量后,它就不再具有反应性,因为它不再触发源对象上的 get/set proxy 陷阱。

这看起来像是一个完美的解决方案,可以使所有事物都变成响应式。但是有个问题!根据定义,proxy只适用于复杂类型。这些包括对象、数组、映射和集合。要使一个原始类型变得反应灵敏,我们仍然需要使用代理,但首先我们必须将其包装在一个对象中。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
function ref(value) {
  const refObject = {
    get value() {
      track(refObject, 'value')
      return value
    },
    set value(newValue) {
      value = newValue
      trigger(refObject, 'value')
    }
  }
  return refObject
}

这解释了为什么必须在 script setup 中使用烦人的 .value 。而且,再次重构或重新分配给本地变量也是行不通的。

总结

那么,为什么需要 Ref 和 Reactive的答案是:Proxy。对于复杂类型,它们可以直接使用,但对于原始类型,需要创建一个代理对象。

希望,理解Vue的内部工作原理可以使你更有效,并且可以消除 refreactive 之间的任何混淆。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-08-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
vue3实战-完全掌握ref、reactive
知道大家使用 Vue3 的时候有没有这样的疑惑,“ref、rective 都能创建一个响应式对象,我该如何选择?”,“为什么响应式对象解构之后就失去了响应式?应该如何处理?” 今天咱们就来全面盘点一下 ref、reactive,相信看完你一定会有不一样的收获,一起学起来吧!
yyds2026
2022/11/01
3.5K0
前端必读:Vue响应式系统大PK
响应式系统(Reactivity systems)是现代前端框架的关键部分之一。应用系统的的高度交互性、动态性和响应能力全靠它支持。每个Web开发人员而言都应该了解这一系统的功能和实践操作。
葡萄城控件
2021/05/20
1K0
vue3之Composition API详解
没有Composition API之前vue相关业务的代码需要配置到option的特定的区域,中小型项目是没有问题的,但是在大型项目中会导致后期的维护性比较复杂,同时代码可复用性不高。Vue3.x中的composition-api就是为了解决这个问题而生的
前端进阶之旅
2021/10/16
2.2K0
vue3之Composition API详解
Vue3学习笔记(二)——组合式API(Composition API)
官方文档: https://v3.cn.vuejs.org/guide/composition-api-introduction.html
张果
2022/10/31
4.5K0
Vue3学习笔记(二)——组合式API(Composition API)
全面了解Vue3的 ref 和相关函数和计算属性
在vue3里面,我们可以通过 reactive 来实现引用类型的响应性,那么基础类型的响应性如何来实现呢?
用户1174620
2021/04/13
1.5K0
【揭秘Vue核心】深入解析Object.defineProperty和Proxy的区别,让你秒懂!
Object.defineProperty 和 Proxy 是用于实现响应式数据的两种不同方式。
奋飛
2023/07/10
7810
【揭秘Vue核心】深入解析Object.defineProperty和Proxy的区别,让你秒懂!
Vue的ref和reactive的区别-源码解读
在看vueuse官方文档的时候,有这么一段话 Use ref instead of reactive whenever possible
韦东锏
2024/05/30
1160
Vue的ref和reactive的区别-源码解读
vue3笔记1 组件配置API
vue2中的数据,计算属性,方法,生命周期钩子等都可以在setup函数中构造 setup函数返回:
路过君
2022/04/13
4100
Vue3基础
官方文档:https://cli.vuejs.org/zh/guide/creating-a-project.html#vue-create
六个周
2022/10/28
1K0
Vue3基础
vue3中的reactive、ref、toRef和toRefs
reactive用于创建响应式对象,它返回一个对象的响应式代理。即:它返回的对象以及其中嵌套的对象都会通过 Proxy 包裹;当响应式对象被访问时,触发getter方法;当响应式对象被修改时,触发setter方法。在使用响应式对象时,我们可以像普通对象一样访问和修改数据。
九仞山
2023/10/14
2.6K0
Vue3 源码解析(六):响应式原理与 reactive
今天这篇文章是笔者会带着大家一起深入剖析 Vue3 的响应式原理实现,以及在响应式基础 API 中的 reactive 是如何实现的。对于 Vue 框架来说,其非侵入的响应式系统是最独特的特性之一了,所以不论任何一个版本的 Vue,在熟悉其基础用法后,响应式原理都是笔者最想优先了解的部分,也是阅读源码时必细细研究的部分。毕竟知己知彼百战不殆,当你使用 Vue 时,掌握了响应式原理一定会让你的 coding 过程更加游刃有余的。
Originalee
2021/06/11
1.5K1
Vue3 源码解析(六):响应式原理与 reactive
常见经典vue面试题(面试必问)
如果不使用 key,Vue 会使用一种最大限度减少动态元素并且尽可能的尝试就地修改/复用相同类型元素的算法。key 是为 Vue 中 vnode 的唯一标记,通过这个 key,我们的 diff 操作可以更准确、更快速
bb_xiaxia1998
2022/12/14
1K0
vue3 day03
reactive对比ref 从定义角度对比 ref用来定义:基本数据类型 reactive用来定义: 对象(或数组)类型数据 备注: ref也可以用来定义对象(或数组)类型数据,它内部会自动通过reactive转为代理对象 从原理角度来对比 ref使用了是Object.defineProperty()的get和set来实现响应式(数据劫持) reactive使用了es6的proxy来实现响应式(数据劫持),并通过Reflect操作源对象内部的数据 从使用角度对比 ref定义的数据: 操作数据时需要使用.va
花花522
2023/03/07
2320
vue3 day03
vue 随记(4):响应式的进化
正常来说,被监听的数据在初始化时就已经被全部监听了。后续并不会再次这种时候,不得不通过vm.$set(全局 Vue.set 的别名。)来处理新增的属性。
一粒小麦
2020/07/23
7080
vue 随记(4):响应式的进化
深入源码彻底搞清vue3中reactive和ref的区别
在vue3的日常开发中,我发现很多人都是基于自己的习惯reactive或ref一把梭,虽然这样都可以实现需求,既然这样那为什么已经有了reactive还需要再去设计一个ref呢?这两者的实际运用场景以及区别是什么呢?
inline705
2022/09/27
1.3K0
深入源码彻底搞清vue3中reactive和ref的区别
阿里前端高频vue面试题(边面边更)
Vue2:Object.defineProperty 重新定义data 中所有的属性,Object.defineProperty 可以使数据的获取与设置增加一个拦截的功能,拦截属性的获取,进行依赖收集。拦截属性的更新操作,进行通知。
bb_xiaxia1998
2022/10/14
8450
petite-vue源码剖析-逐行解读@vue/reactivity之reactive
在petite-vue中我们通过reactive构建上下文对象,并将根据状态渲染UI的逻辑作为入参传递给effect,然后神奇的事情发生了,当状态发生变化时将自动触发UI重新渲染。那么到底这是怎么做到的呢? @vue/reactivity功能十分丰富,而petite-vue仅使用到reactive和effect两个最基本的API,作为入门本文将仅仅对这两个API进行源码解读。
^_^肥仔John
2022/05/09
7060
Vue3源码06: reactive、ref相关api源码实现
函数createReactiveObject最关键的逻辑,就是创建了一个Proxy实例并设置处理器。根据类型不同,处理器可能是处理集合类对象的处理器或者处理普通对象的处理器。从函数reactive代码可知,传入的处理器分别是mutableHandlers和mutableCollectionHandlers。接下来我们看看这两个处理器中的代码实现。
杨艺韬
2022/09/27
8040
vue3.0 源码解析一 :响应式原理(上)
从本文开始,我们正式进入vue3.0 源码解析流程。个人觉得从ceateApp入手并不是最佳的学习方案,所以我们先从composition-api响应式原理入手,共同学习vue3.0带来的哪些翻天覆地的变化。
用户6835371
2021/06/01
5750
vue3.0 源码解析一 :响应式原理(上)
[实战] 为了学好 React Hooks, 我抄了 Vue Composition API, 真香
前几篇文章都在讲 React 的 Concurrent 模式, 很多读者都看懵了,这一篇来点轻松的,蹭了一下 Vue 3.0 的热度。讲讲如何在 React 下实现 Vue Composition API(下面简称VCA),只是个玩具,别当真。
_sx_
2019/11/28
3.2K0
[实战] 为了学好 React Hooks, 我抄了 Vue Composition API, 真香
相关推荐
vue3实战-完全掌握ref、reactive
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验