vue3 数据响应式遇到的问题

问题背景

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

  1. 对象数组中,使用索引值更改数据,数据变化了页面没有变化
  • 类似代码 - options api使用的是this指针方式,但是问题是一样的
css 复制代码
cosnt arr = reactive({
  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"],但是再往下层级的并没有被转化成响应式,所以此时我们可以这样去解决

css 复制代码
consr newArr = arr["arr1"]
newArr[0] = {"name": "test11","name2": "test22","name3": "test33",}
arr["arr1"] = newArr[0]
  1. 解构失去响应式
php 复制代码
    const test = reactive({
      arr: { name: '111'}
    })
    // 解构会失去响应性!
    const { arr } = test
    // 修改 user 不会触发界面更新
    arr.name = '李四'  //界面不更新

    //解决方案
    // 1、
    const { arr } = toRefs(test)
    // 2、尽量不要解构响应式数据
  1. 新增属性不响应
php 复制代码
    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 用于优化深层嵌套对象的性能问题

相关推荐
Data analyse45639 分钟前
Cookie过期引发UV上涨的复核方法
服务器·前端·数据分析·uv
Highcharts.js40 分钟前
图表开发实战总结| 7 条“黄金法则”与“性能铁律”
前端·javascript·vue.js·编辑器·时序数据库·highcharts
Helix25042 分钟前
Electron、WebView 框架与 HTA 对比:桌面应用选型、安全性与现代替代方案
前端·javascript·electron·webview·vbscript·hta·本地html应用
开开心心就好1 小时前
办公软件卸载不干净?专用工具一键清残留
java·前端·人工智能·智能手机·kafka·excel·memcache
静默回滚1 小时前
图片能显示,画进canvas却空白:像素面积上限
前端
补码缩写1 小时前
canvas大图内存怎么算:宽×高×4只是第一份
前端
coding漫漫长路1 小时前
img.decode()报错的图能画,load成功的却是空的
前端
不可能片场1 小时前
AI视频首尾帧控制 用参考图定住镜头
前端·electron
修炼的dance2 小时前
canvas最大能开多大:先看面积,再看导出格式
前端
薛一半2 小时前
React-Redux核心原理与容器组件实战
前端·javascript·react.js