vue3.0(五) reactive全家桶

news2024/10/5 21:15:01

文章目录

  • 1 reactive
    • 1.1 reactive的应用
    • 1.2 reactive的特点
    • 1.3 reactive的注意
    • 1.4 reactive的局限性
  • 2 toRefs
  • 3 isReactive
  • 4 shallowReactive
  • 5 readonly
    • 5.1 readonly 详细信息
    • 5.2 readonly函数创建一个只读的响应式对象
    • 5.3 如何修改嵌套在只读响应式对象中的对象?
  • 6 isReadonly
  • 7 shallowReadonly
  • 8 isProxy
  • 总结


1 reactive

1.1 reactive的应用

reactive是另一种声明响应式状态的方式,与将内部值包装在特殊对象中的 ref 不同,reactive() 将使对象本身具有响应性:

import { reactive } from 'vue'
// 声明state
const state = reactive({ count: 0 })
// js中的应用和ref不同不需要value
 console.log(state)
// html模版中应用
 <div>{{ state.count }}</div>

响应式对象是 JavaScript 代理,其行为就和普通对象一样。不同的是,Vue 能够拦截对响应式对象所有属性的访问和修改,以便进行依赖追踪和触发更新。
reactive() 将深层地转换对象:当访问嵌套对象时,它们也会被 reactive() 包装。当 ref 的值是一个对象时,ref() 也会在内部调用它。与浅层 ref 类似,这里也有一个 shallowReactive() API 可以选择退出深层响应性。

1.2 reactive的特点

  • 实现引用类型数据的响应式,如数组、对象等
  • ref去创建引用类型的响应式,其实内部也是调用了reactive
  • reactive创建的响应式对象,调用时不用.value

在Vue3中,reactive函数是用于创建响应式对象的函数。它接收一个普通对象作为参数,返回一个代理对象。这个代理对象可以拦截对象的get和set操作,并在其中实现响应式的逻辑。当我们读取代理对象的属性时,会触发依赖收集;当我们修改代理对象的属性时,会触发相应的依赖更新。在调用reactive函数时,Vue3会使用Proxy对象对传入的对象进行代理,从而实现响应式的特性。

1.3 reactive的注意

  • reactive() 返回的是一个原始对象的 Proxy,它和原始对象是不相等的:
    const obj = {}
    const proxy = reactive(obj)
    // 代理对象和原始对象不是全等的
    console.log(proxy === obj) // false
    
  • 为保证访问代理的一致性,对同一个原始对象调用 reactive() 会总是返回同样的代理对象,而对一个已存在的代理对象调用 reactive() 会返回其本身:
    const obj = {}
    const proxy = reactive(obj)
    // 在同一个对象上调用 reactive() 会返回相同的代理
    console.log(proxy === reactive(obj)) // true
    // 在一个代理上调用 reactive() 会返回它自己
    console.log(reactive(proxy) === proxy) // true
    

1.4 reactive的局限性

  1. 有限的值类型:它只能用于对象类型 (对象、数组和如 Map、Set 这样的集合类型)。它不能持有如 string、number 或 boolean 这样的原始类型。
  2. 不能替换整个对象:由于 Vue 的响应式跟踪是通过属性访问实现的,因此我们必须始终保持对响应式对象的相同引用。这意味着我们不能轻易地“替换”响应式对象,因为这样的话与第一个引用的响应性连接将丢失:
<template>
  <div>{{ state.count }}</div>
  <button @click="mutateDeeply">修改数据</button>
</template>
<script lang="ts">
import { defineComponent, reactive } from 'vue'
export default defineComponent({
  setup () {
    let state = reactive({ count: 1 })
    console.log(state)
    function mutateDeeply () {
    // 对state进行替换响应式对象
    // 上面的 ({ count: 0 }) 引用将不再被追踪
	// (响应性连接已丢失!)
      state = reactive({ count: 2 })
      console.log(state, state.count)
    }
    return {
      mutateDeeply,
      state
    }
  }
})
</script>

当点击修改数据按钮时,打印的是赋值的数据,但是页面并未更新,(响应性连接已丢失!)

  1. 对解构操作不友好:当我们将响应式对象的原始类型属性解构为本地变量时,或者将该属性传递给函数时,我们将丢失响应性连接:
    <template>
      <div>{{ state.count }}</div>
      <button @click="mutateDeeply">修改数据</button>
    </template>
    <script lang="ts">
    import { defineComponent, ref, reactive } from 'vue'
    export default defineComponent({
      setup () {
        const state = reactive({ count: 1 })
        console.log(state)
        function mutateDeeply () {
          // 当解构时,count 已经与 state.count 断开连接
          let { count } = state
          // 不会影响原始的 state
          count++
          console.log(state, state.count, count)
        }
        return {
          container,
          mutateDeeply,
          state
        }
      }
    })
    </script>
    <style scoped>
    </style>
    

上述代码执行结果

2 toRefs

  1. 将一个响应式对象转换为一个普通对象,这个普通对象的每个属性都是指向源对象相应属性的 ref。每个单独的 ref 都是使用 toRef() 创建的。
     const state = reactive({
       foo: 1,
        bar: 2
      })
      const stateAsRefs = toRefs(state)
      /*
      stateAsRefs 的类型:{
        foo: Ref<number>,
        bar: Ref<number>
      }
      */
    
      // 这个 ref 和源属性已经“链接上了”
      console.log(stateAsRefs) // {foo: ObjectRefImpl, bar: ObjectRefImpl}
      state.foo++
      console.log(stateAsRefs.foo.value)// 2
      stateAsRefs.foo.value++
      console.log(state.foo)// 3
    
    1. 组件可以解构/展开返回的对象而不会失去响应性:
    <template>
      <div>{{ state.foo }}</div>
      <div>{{ state.bar }}</div>
      <button @click="mutateDeeply">修改数据</button>
    </template>
    <script lang="ts">
    import { defineComponent, reactive, toRefs } from 'vue'
    export default defineComponent({
      setup () {
        const state = reactive({
          foo: 1,
          bar: 2
        })
        function useFeatureX () {
          return toRefs(state)
        }
        function mutateDeeply () {
          const { foo, bar } = useFeatureX()
          foo.value++
          bar.value++
          console.log(foo.value, bar.value)
        }
        return {
          mutateDeeply,
          state
        }
      }
    })
    </script>
    <style scoped>
    </style>
    

上述代码执行效果
toRefs 在调用时只会为源对象上可以枚举的属性创建 ref。如果要为可能还不存在的属性创建 ref,请改用 toRef。

3 isReactive

检查一个对象是否是由 reactive() 或 shallowReactive() 创建的代理。

const state = readonly(reactive({
  count: 1,
  name: 'Tom'
}))

console.log(state.count)// 1
console.log(state.name)// Tom
console.log(isReactive(state)) // true

4 shallowReactive

  1. reactive() 的浅层作用形式。
  2. 和 reactive() 不同,这里没有深层级的转换:一个浅层响应式对象里只有根级别的属性是响应式的。属性的值会被原样存储和暴露,这也意味着值为 ref 的属性不会被自动解包了
<template>
  <div>{{ state.foo }}</div>
  <div>{{ state.nested.bar }}</div>
  <button @click="mutateDeeply">修改数据</button>
</template>
<script lang="ts">
import { defineComponent, shallowReactive, isReactive } from 'vue'
export default defineComponent({
  setup () {
    const state = shallowReactive({
      foo: 1,
      nested: {
        bar: 2
      }
    })
    // ...但下层嵌套对象不会被转为响应式
    console.log(isReactive(state.nested)) // false
    function mutateDeeply () {
      state.foo++
      // 不是响应式的 数据
      state.nested.bar++
      console.log(state.foo, state.nested, state.nested.bar)
    }
    return {
      mutateDeeply,
      state
    }
  }
})
</script>

5 readonly

接受一个对象 (不论是响应式还是普通的) 或是一个 ref,返回一个原值的只读代理。

5.1 readonly 详细信息

  • 只读代理是深层的:对任何嵌套属性的访问都将是只读的。它的 ref 解包行为与 reactive() 相同,但解包得到的值是只读的。
  • 要避免深层级的转换行为,请使用 shallowReadonly() 作替代。

5.2 readonly函数创建一个只读的响应式对象

  const state = readonly(reactive({
      count: 1,
      name: 'Tom'
    }))

    console.log(state.count)// 1
    console.log(state.name)// Tom

5.3 如何修改嵌套在只读响应式对象中的对象?

使用readOnly函数创建的只读对象,内部的属性无法修改

   const state = readonly(reactive({
      count: 1,
      name: 'Tom'
    }))

    console.log(state.count)// 1
    state.name = 'diXi' // 输出警告信息,不会触发依赖更新
    console.log(state.name)// Tom

在这里插入图片描述
注意:使用 readonly 函数创建的只读响应式对象是深层只读的。也就是说,当我们尝试修改嵌套在只读响应式对象中的对象时,会输出警告信息,不会触发相应的依赖更新。

6 isReadonly

  • 检查传入的值是否为只读对象。只读对象的属性可以更改,但他们不能通过传入的对象直接赋值。
  • 通过 readonly() 和 shallowReadonly() 创建的代理都是只读的,因为他们是没有 set 函数的 computed() ref。
const state = readonly(reactive({
   count: 1,
   name: 'Tom'
 }))

 console.log(state.count)// 1
 console.log(state.name)// Tom
 console.log(isReadonly(state)) // true

7 shallowReadonly

  • readonly() 的浅层作用形式
  • 和 readonly() 不同,这里没有深层级的转换:只有根层级的属性变为了只读。属性的值都会被原样存储和暴露,这也意味着值为 ref 的属性不会被自动解包了。
    const state1 = readonly(reactive({
      foo: 1,
      nested: {
        bar: 2
      }
    }))
    const state = shallowReadonly(reactive({
      foo: 1,
      nested: {
        bar: 2
      }
    }))
    console.log(state.nested.bar++)
    // console.log(state1.nested.bar++) // 报错 Cannot assign to 'bar' because it is a read-only property
    // console.log(state.foo++) // 报错 Cannot assign to 'bar' because it is a read-only property
    // console.log(state1.foo++) // 报错 Cannot assign to 'bar' because it is a read-only property
    // ...但可以更改下层嵌套对象
    isReadonly(state.nested) // false
    

8 isProxy

检查一个对象是否是由 reactive()、readonly()、shallowReactive() 或 shallowReadonly() 创建的代理。

   const state = readonly(reactive({
      count: 1,
      name: 'Tom'
    }))

 console.log(state.count)// 1
 console.log(state.name)// Tom
 console.log(isProxy(state)) // true

总结

Vue3中用于创建响应式对象的三个函数:
reactive、readonly和shallowReactive。
reactive函数用于创建深层响应式对象,
shallowReactive函数用于创建浅层响应式对象,
readonly函数用于创建深层只读响应式对象,
shallowReadonly函数用于创建浅层只读响应式对象。
这些函数可以帮助我们快速创建响应式数据,实现数据的自动更新。
isProxy,isReadonly,isReactive判断是否是相应是对象
isProxy 检查一个对象是否是由 reactive()、readonly()、shallowReactive() 或 shallowReadonly() 创建的代理。
isReadonly 检查传入的值是否为 readonly() 和 shallowReadonly() 创建的只读对象。
isReactive 检查一个对象是否是由 reactive() 或 shallowReactive() 创建的代理。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1660015.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SG3225EEN在PAM4光模块和400G,QSFP-DD光模块中的应用

爱普生晶振SG3225EEN&#xff0c;156.25MHz在PAM4光模块和QSFP-DD光模块中的应用。光模块市场已发展至400G光模块&#xff0c;那么PAM4光模块和400G QSFPDD光模块有哪些区别呢?SG3225EEN又是怎么应用在PAM4光模块和QSFP-DD光模块中的呢? 首先介绍的是PAM4光模块:PAM4是PAM(脉…

爱思控AQMDBLS-Ax/Bx/Mx/T 系列无刷电机驱动器使用

履带车配置 AQMDBLS-Ax/Bx/Mx/T 系列无刷电机驱动器使用大致需要以下几个步骤。 1&#xff09; 阅读用户使用说明书、了解驱动器的性能、明确控制目的&#xff1b;2&#xff09; 根据电机和驱动器的接线原理&#xff0c;正确接线&#xff1b;3&#xff09; 使用 485 通讯控制&…

FileLink跨网文件摆渡系统:保障数据安全,促进业务高效协同

FileLink跨网文件摆渡系统&#xff0c;作为一种先进的文件传输解决方案&#xff0c;正逐渐在企业级应用中崭露头角。它打通了不同网络之间的隔阂&#xff0c;使得文件能够安全、高效地从一个网络传输到另一个网络。 FileLink跨网文件摆渡系统基于先进的加密技术和数据传输协议&…

亚信安慧AntDB:解锁数智化的新时代

亚信安慧AntDB的融合实时的特性使得它在数据库领域独树一帜。传统的数据库系统往往只能追求数据的准确性和一致性&#xff0c;但在实际的业务场景中&#xff0c;这些特性并不能满足企业的需求。AntDB的出现打破了传统束缚&#xff0c;为企业带来了全新的数据处理方式&#xff0…

【Linux网络编程】高级IO——五种IO模型

高级IO 1.什么是IO&#xff1f;什么是高效的IO&#xff1f;2.有那些IO的方式&#xff1f;这么多的方式&#xff0c;有那些是高效的&#xff1f;3.五种IO模型4.高级IO重要概念5.非阻塞IO 点赞&#x1f44d;&#x1f44d;收藏&#x1f31f;&#x1f31f;关注&#x1f496;&#x…

shopro商城 源码搭建/部署/上线/运营/售后/更新

基于Fastadmin和Uniapp进行开发的多平台&#xff08;微信公众号、微信小程序、H5网页、Android-App、IOS-App&#xff09;购物商城&#xff0c;拥有强大的店铺装修、自定义模板、路由同步、多端支付&#xff08;微信&#xff0c;支付宝&#xff09;、多规格商品、运费模板、多地…

突发!31篇文章被撤!这本Springer旗下SCI,开始大面积撤稿,原因涉及同行评议!

【欧亚科睿学术】 近期&#xff0c;期刊JOURNAL OF COMBINATORIAL OPTIMIZATION撤回了31篇文章&#xff0c;大部分文章都是由中国学者参与。主要原因是包括但不限于&#xff1a;编辑处理和同行评议过程的妥协&#xff0c;不恰当或不相关的参考文献&#xff0c;或者不在期刊或客…

如何高效合并Python字典?掌握这些技巧,让你的代码更优雅!

在Python中&#xff0c;字典&#xff08;Dictionary&#xff09;是一种非常有用的数据结构&#xff0c;它允许我们以键值对的形式存储数据。在日常编程中&#xff0c;我们经常需要将两个或多个字典合并为一个。幸运的是&#xff0c;Python提供了一种简洁而高效的方式来实现这一…

探索财富新纪元:订单排队模式引领企业革新之路

尊敬的企业家们&#xff0c;大家好&#xff01;在现今这个竞争激烈的商业环境中&#xff0c;寻找一种既高效又具持续性的商业策略&#xff0c;是每个企业家都关注的焦点。今天&#xff0c;我要为您揭示一种前沿的商业模式——订单排队模式&#xff0c;它可能为您的企业开启全新…

金蝶BI应收分析报表:关于应收,这样分析

这是一张出自奥威-金蝶BI方案的BI应收分析报表&#xff0c;是一张综合运用了筛选、内存计算等智能分析功能以及数据可视化图表打造而成的BI数据可视化分析报表&#xff0c;可以让企业运用决策层快速知道应收账款有多少&#xff1f;账龄如何&#xff1f;周转情况如何&#xff1f…

2024数维杯数学建模A题B题C题思路+模型+代码(开赛后第一时间更新)

2024数维杯数学建模A题B题C题思路模型代码&#xff08;开赛后第一时间更新&#xff09; https://mbd.pub/o/bread/ZpWakpdq https://mbd.pub/o/bread/ZpWakpdq 2024年第九届数维杯大学生数学建模挑战赛参赛规则 竞赛要求及论文提交方式; ①本次参赛作品统一在线提交到竞赛…

echarts-gl 离线3D地图

1、安装依赖 echarts-gl 与 echarts 版本关系&#xff1a; "echarts": "^5.2.0", "echarts-gl": "^2.0.8"# 执行安装 yarn add echarts-gl2、下载离线地图 免费下载实时更新的geoJson数据、行政区划边界数据、区划边界坐标集合_…

2024年北京服贸会媒体邀约资源有哪些?

传媒如春雨&#xff0c;润物细无声&#xff0c;大家好&#xff0c;我是51媒体网胡老师。 2024年北京服贸会&#xff08;中国国际服务贸易交易会&#xff0c;简称CIFTIS&#xff09;作为中国重要的国际性服务贸易盛会&#xff0c;会吸引众多媒体的关注和参与。媒体邀约资源通常…

【记录】常见的前端设计系统(Design System)

解释一下设计系统的定义&#xff0c;以及在国内&#xff0c;都有那些优秀的设计系统可以学习&#xff0c;希望可以帮到大家。 什么是设计系统&#xff08;Design System)&#xff1f; 设计系统&#xff08;Design System&#xff09;是一套综合性的指导原则、组件和规则&…

标准参编征集|《第三方运维服务水平评价指南 工业废水处理设施》

目前&#xff0c;对于工业废水处理设施第三方运维服务的标准&#xff0c;国家和行业未曾出台有针对性的评价标准和规范&#xff0c;工业企业和工业园区对第三方运维服务的监督、考核、评价体系需要进一步补充和完善。 本标准的编制旨在帮助第三方运营单位从运营技术和管理举措…

如何使用XCTest进行ios自动化测试?

iOS自动化测试框架有哪些&#xff1f; iOS自动化测试框架有很多&#xff0c;以下是一些常用的iOS自动化测试框架&#xff1a; XCTest&#xff1a; XCTest是苹果官方提供的iOS自动化测试框架&#xff0c;可以用于单元测试和UI测试。 Appium&#xff1a; Appium是一个跨平台的自…

【Linux系统编程】第十四弹---进度条

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】【C详解】【Linux系统编程】 目录 1、回车和换行 2、观察回车换行现象 3、缓冲区 4、usleep和fflush函数 5、简单倒计时 6、进度条 6.1、版本一 6.2、版本…

【数据结构】单链表专题详细分析

与其临渊羡鱼&#xff0c;不如退而结网。&#x1f493;&#x1f493;&#x1f493; 目录 •✨说在前面 &#x1f34b;知识点一&#xff1a;什么是链表&#xff1f; • &#x1f330;1.链表的概念 • &#x1f330;2.链表的结构 • &#x1f330;3.链表的分类 &#x1f34b;…

青动CRM源码搭建/部署/上线/运营/售后/更新

CRM是一款基于thinkphpfastadmin开发的客户管理系统。旨在助力企业销售全流程精细化、数字化管理&#xff0c;全面解决企业销售团队的全流程客户服务难题&#xff0c;帮助企业有效盘 活客户资源、量化销售行为&#xff0c;合理配置资源、建立科学销售体系&#xff0c;提升销售业…

无限免费泛域名SSL证书申请

如今https访问已经成为了网络安全的标识&#xff0c;SSL证书也成为了保护网站内用户信息安全和加密信息交互的手段之一。自2019年等保2.0的相应政策出台后&#xff0c;实现网站https访问也是必经环节之一。 当下SSL证书的相关政策也一直备受关注&#xff0c;有免费的SSL证书也…