所遇到的响应式问题

问题背景

是在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 用于优化深层嵌套对象的性能问题

相关推荐
Ruihong2 小时前
你的 Vue v-for,VuReact 会编译成什么样的 React 代码?
vue.js·react.js·面试
M ? A2 小时前
你的 Vue 路由,VuReact 会编译成什么样的 React 路由?
前端·javascript·vue.js·经验分享·react.js·面试·vureact
L.Cheng2 小时前
谷歌浏览器如何禁用自动更新_Chrome关闭后台升级程序
前端·chrome
donecoding2 小时前
类型与语法的“直觉对齐”:TS 切入的 Go 语言初体验
前端·typescript·go
web守墓人2 小时前
【linux】Mubuntu v1.0.7发布:支持codex cli完整运行
前端·codex
WYiQIU2 小时前
宇树科技Web前端岗(AI方向),这不算泄题吧......
前端·vue.js·人工智能·笔记·科技·面试·职场和发展
Januea2 小时前
Chrome的Fetch/XHR是什么?
前端·chrome
betazhou2 小时前
TDSQL-PG创建测试表并定时插入数据模拟生产
前端·javascript·数据库·tdsql·tdsql-pg
W.A委员会2 小时前
地址栏输入url到显示画面
前端·网络