前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >vue3中的reactive和ref

vue3中的reactive和ref

原创
作者头像
用户10562852
发布2023-06-09 11:19:28
3750
发布2023-06-09 11:19:28
举报
文章被收录于专栏:前端不难

一、关于reactive

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

reactive的特点

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

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

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

代码语言:javascript
复制
let o = {name: 'zs', age: 10}
let obj = reactive(o)
console.log(obj === o) // false

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

代码语言:javascript
复制
let o = {name: 'zs', info: {age: 1}}
let obj = reactive(o)
setInterval(() => {
  obj.info.age++
}, 2000)

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

代码语言:javascript
复制
let o = {name: 'zs', info: {age: 1}}
let obj = reactive(o)
console.log(obj.info) // Proxy(Object) {age: 1}

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

代码语言:javascript
复制
<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 类型的话不会失去响应式
代码语言:javascript
复制
<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 的话不会被换成响应式的

代码语言:javascript
复制
<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 被传递给函数或是从一般对象上被解构时,不会丢失响应性

代码语言:javascript
复制
let obj = {
  name: ref('zs'),
  age: ref(12)
}
let {age} = obj
setInterval(() => {
  age.value++
}, 2000)

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

3、ref 在模板中的解包

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

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

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、关于reactive
    • reactive的特点
      • reactive 的局限性
      • 二、关于 ref
        • ref 特点
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档