所遇到的响应式问题

问题背景

是在vue2项目升级vue3项目中遇到的,因为升级项目并没有使用vue的Composition api 而是使用Options api,所有复杂类型变量默认使用reactive进行响应式,问题也是从这出现的

  1. 对象数组中,使用索引值更改数据,数据变化了页面没有变化
  • 类似代码 - options api使用的是this指针方式,但是问题是一样的
javascript 复制代码
  arr1:[
    {
        "name": "test",
        "name2": "test2",
        "name3": "test3",
    },
    {
        "name": "test",
        "name2": "test2",
        "name3": "test3",
    }    ]      })    
    arr["arr1"][0] = {"name": "test11","name2": "test22","name3": "test33",}  

这个时候我们从vue3的源代码入手,分析原因,具体只需要看proxy 的 get方法

源代码地址 packages\reactivity\src\baseHandlers.ts

有个BaseReactiveHandler方法

当我们触发get方法时,如果还是复杂类型,需要在调用reactive将其转化成响应式,所以Vue的依赖收集是"按需"的,具有一种懒惰性质,层级较深的复杂类型数据不是在声明式就被全部转化成响应式,而是在获取时逐层转化的

这个时候我们回看我们的问题,当我们执行arr["arr1"][0] = {"name": "test11","name2": "test22","name3": "test33",}的时候,只触发了arr["arr1"],但是再往下层级的并没有被转化成响应式,所以此时我们可以这样去解决

javascript 复制代码
"test11","name2": "test22","name3": "test33",} arr["arr1"] = newArr[0]
  1. 解构失去响应式
javascript 复制代码
const test = reactive({
   arr: { name: '111'}    
})    
   // 解构会失去响应性!    
   const { arr } = test    
   // 修改 user 不会触发界面更新    
   arr.name = '李四'  //界面不更新
   //解决方案   
   // 1、    
   const { arr } = toRefs(test)    
   // 2、尽量不要解构响应式数据
  
  1. Object新增属性不响应
javascript 复制代码
const test = reactive({
  arr: { name: '111'}    
  })
  // 修改 user 不会触发界面更新    
  test.arr.age= 22  
  //界面不更新
  // 解决方法 使用 Object.assign    
  Object.assign(test.arr, { age: 22 })  //  触发更新
 

总结

所以在vue3 开发中,如果使用options api方式,就需要尽量注意多层嵌套对象,如果使用Composition api,尽量使用 ref 去定义变量,并且针对嵌套层级较深的变量最好使用ShallowRef ShallowReactive 用于优化深层嵌套对象的性能问题

相关推荐
胡志辉的博客5 分钟前
【完全开源】IP 纯净度检测 可一键部署到自己的CF
前端·javascript·chrome·ip·chromium
Hilaku31 分钟前
作为面试官,我最怕遇到什么样的候选人?
前端·javascript·程序员
一 乐32 分钟前
自习室座位预约管理系统|基于springboot + vue自习室座位预约管理系统(源码+数据库+文档)
java·vue.js·spring boot
TiDi1 小时前
Pinia优化重复请求
前端
web3d5201 小时前
01-用 Leafletjs 10 分钟搭一张水利一张图(Vue3 + Vite 实战)
前端·javascript
晚安日记wanna1 小时前
Vue2 的 defineProperty 差在哪四层追问筛掉九成候选人
前端·vue.js·面试
TiDi1 小时前
吸顶导航交互实现
前端
kisshyshy1 小时前
从Props透传到自定义Hook:系统梳理React跨层级通信与逻辑复用
前端·架构·代码规范
yume_sibai1 小时前
05-Flutter实战项目
前端·flutter
涛涛ing2 小时前
React 19.3 发布,但真正的赢家是 StyleX:当 AI 成为框架的“第一用户”
前端