vue3中的reactive和ref

一、关于reactive

reactive 接受一个对象类型的值,返回一个对象的代理。

reactive的特点

1、仅对对象类型有效(对象、数组和 Map、Set 这样的集合类型),而对 string、number 和 boolean 这样的 原始类型 无效。

let count = reactive(0)
setInterval(() => {
  count++ // 数据是变了,但是页面并不会变,因为不是响应式的数据
}, 2000)

2、reactive() 返回的是一个原始对象的 Proxy,它和原始对象是不相等的。

let o = {name: 'zs', age: 10}
let obj = reactive(o)
console.log(obj === o) // false

3、状态都是默认深层响应式的。这意味着即使在更改深层次的对象或数组,你的改动也能被检测到。也可以直接创建一个浅层响应式对象(shallowReactive()),它们仅在顶层具有响应性。

let o = {name: 'zs', info: {age: 1}}
let obj = reactive(o)
setInterval(() => {
  obj.info.age++
}, 2000)

4、响应式对象内的嵌套对象依然是代理(Proxy)

let o = {name: 'zs', info: {age: 1}}
let obj = reactive(o)
console.log(obj.info) // Proxy(Object) {age: 1}

5、当响应式对象改变时,原始对象的值也会被改变

<script setup>
import {reactive} from 'vue'

let o = {name: 'zs', info: {age: 1}}
let obj = reactive(o)
setInterval(() => {
  obj.info.age++
  // console.log(o);
}, 2000)
</script>

<template>
  <div>
    {{ obj }}
    <!-- {{ o }} -->
  </div>
</template>

        上面的代码我发现一个奇怪的问题,当正常执行上面代码时,看不出任何问题,但是如果把下面的代码注释解除掉,就会发现怎么 o 也是响应式的了?但是在控制台中打印出来并不是响应式的啊,如果再把 obj 注释,此时 o 不是响应式的,这里其实o并不是响应式的,只是由于obj 改变会影响视图更新,重新渲染页面后,拿到最新数据,看似 o 是响应式的,实际上只是由于,obj的改变,导致 o 也改变然后视图,数据更新了而已。

reactive 的局限性

1、上面第一点。

2、将响应式对象的属性赋值或解构至本地变量时,或是将该属性传入一个函数时,我们会失去响应性。

  • 这里的属性值应该是一个基本类型,object 类型的话不会失去响应式
<script setup>
import {reactive} from 'vue'

let o = {name: 'zs', info: {age: 1}}
let obj = reactive(o)
// let {info} = obj // 依旧时响应式的数据
let info = obj.info // 依旧时响应式的数据
// let age = obj.info.age // age 不是响应式的

setInterval(() => {
  info.age++
  age++
}, 2000)
</script>

<template>
  <div>
    {{ info }}
    <!-- {{ age}} -->
  </div>
</template>

二、关于 ref

ref() 方法来允许我们创建可以使用任何值类型的响应式 ref,如果我们创建的是一个对象的响应式数据,其实里面原理也是通过 reactive 实现的。

ref() 将传入参数的值包装为一个带 .value 属性的 ref 对象

ref 特点

1、一个包含对象类型值的 ref 可以响应式地替换整个对象,如果是 reactive 的话不会被换成响应式的

<script setup>
let obj = ref({name: 'zs', age: 1})
obj.value = {name: 'lisi', age: 12} // 依旧是响应式的

setInterval(() => {
  obj.value.age++
}, 2000)
</script>

<template>
  <div>
    {{ obj }}
  </div>
</template>

2、ref 被传递给函数或是从一般对象上被解构时,不会丢失响应性

let obj = {
  name: ref('zs'),
  age: ref(12)
}
let {age} = obj
setInterval(() => {
  age.value++
}, 2000)

        注意:最外层的 obj 不能被 ref 或 reactive 设为响应式的,因为reactive结构出来的值不具有响应式。

3、ref 在模板中的解包

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值