当前位置:首页 > 科技  > 软件

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

来源: 责编: 时间:2023-08-09 23:02:05 231观看
导读AICube 开放GPT-4给大家使用以及AI工具助手,可以简化大家生图的的prompt。在使用 Options API 工作时声明响应性数据是直截了当的。data 选项内的所有内容都会自动变为响应性,并在模板中可用。唯一需要注意的是,要将data

cUs28资讯网——每日最新资讯28at.com

AICube 开放GPT-4给大家使用以及AI工具助手,可以简化大家生图的的prompt。cUs28资讯网——每日最新资讯28at.com

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

让我们讨论一下Vue 3中发生了什么变化,以及为什么我们需要两个不同的助手。cUs28资讯网——每日最新资讯28at.com

Vue 2中的响应性

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

每个组件都有一个关联的观察者,用于跟踪在组件的渲染周期中使用的属性。如果依赖项更新,观察者会通知组件,然后触发重新渲染。cUs28资讯网——每日最新资讯28at.com

Vue 3中的响应性

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

可以通过以下简单的例子来理解代理是如何工作的:cUs28资讯网——每日最新资讯28at.com

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方法被称为陷阱,每次访问对象的属性时都会被调用。以类似的方式,可以定义一个设定的陷阱:cUs28资讯网——每日最新资讯28at.com

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 // OKproxy.age = 300 // Error: The age seems invalid

这正是 Vue 3 响应性背后的理念。当使用 reactive 助手声明一个变量时,会使用一个 proxy. 来跟踪任何变化。cUs28资讯网——每日最新资讯28at.com

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。cUs28资讯网——每日最新资讯28at.com

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

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

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 。而且,再次重构或重新分配给本地变量也是行不通的。cUs28资讯网——每日最新资讯28at.com

总结

那么,为什么需要 Ref 和 Reactive 的答案是:Proxy。对于复杂类型,它们可以直接使用,但对于原始类型,需要创建一个代理对象。cUs28资讯网——每日最新资讯28at.com

本文转载自微信公众号「大迁世界」,可以通过以下二维码关注。转载本文请联系大迁世界公众号。cUs28资讯网——每日最新资讯28at.com

cUs28资讯网——每日最新资讯28at.com

本文链接:http://www.28at.com/showinfo-26-5099-0.html[Vue 3] 为什么需要同时使用 Ref 和 Reactive

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: 微软发布.NET 8 最终预览版,正式版计划 11 月 14 日发布

下一篇: 如何优雅地处理RabbitMQ中的消息丢失

标签:
  • 热门焦点
Top