猿创征文|【vue3学习】vue3中实现深拷贝

【Vue3】Vue3 中实现响应式数据深拷贝(针对ref 和 reactive)

​ 关于 浅拷贝深拷贝 的基础知识可参考

【JS学习】–深拷贝与浅拷贝_Sam9029的博客-CSDN博客

​ 关于 refreactive 的基础知识可参考

【Vue3-响应式工具API】ref 和 reactive 使用_Sam9029的博客-CSDN博客


在Vue3 项目 使用 中 响应式数据(主要是引用数据类型) 进行深拷贝,遇到了一些问题,也收获一些经验方法,主要介绍在 vue3 项目中 使用 深拷贝的 方法 以及注意事项

  • 一:JSON序列化
  • 二:for……in 深拷贝手写函数
  • ❗特别注意!不能使用JS的自带APIstructuredClone() 会使得Vue 抛出报错,(目前不知道为什么无法使用,暂时记住不要使用即可)
  • 其他待发现方法

(本文浅解,存在诸多不足,各种细节还有待完善)


目录

文章目录

  • 【Vue3】Vue3 中实现响应式数据深拷贝(针对ref 和 reactive)
    • 目录
    • @[toc]
    • 方法一:JSON 序列化`JSON.parse(JSON.stringify(Obj))`
      • 实例
      • 结果
    • 方法二:`for……in` 手写深拷贝函数 (若需要同时拷贝函数,值为undefined的属性)
      • 实例
      • 结果
      • **❗特别注意!不能使用JS的自带API`structuredClone()` 会使得Vue 抛出报错,(目前不知道为什么无法使用,暂时记住不要使用即可)**
    • 上诉谈论 使用 了 `ref 定义的响应式数据(引用数据类型)`的深拷贝进行说明,同理对于` reactive 定义的响应式数据的` 同样有效!!!

方法一:JSON 序列化JSON.parse(JSON.stringify(Obj))

  • ❗注意,JSON序列化 无法拷贝函数(一般也不会写函数进去)
  • ❗特别注意,JSON序列化 会忽略属性值为 undefined的属性
  • 其他 缺点 参考 文章 【JS学习】–深拷贝与浅拷贝_Sam9029的博客-CSDN博客

实例

<script setup>
import {ref,reactive} from 'vue'
let refObj = ref({
  data:[1,2],
  meta:{
    data:1
  },
  undefined:undefined
})

console.log(refObj.value)  //24行
console.log(JSON.parse(JSON.stringify(refObj.value)))    //25行
</script>

结果

  • ref 定义的对象 是由 Proxy 代理的,所有的值须在 Target 中查看
  • 可有图知,undefined 属性 在深拷贝时 丢失了

猿创征文|【vue3学习】vue3中实现深拷贝_第1张图片


方法二:for……in 手写深拷贝函数 (若需要同时拷贝函数,值为undefined的属性)

  • 此方法可 拷贝 函数 以及值为undefined的属性

实例

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

let refObj = ref({
  data:[1,2],
  meta:{
    data:1
  },
  undefined:undefined,
  null:null
})


console.log("元数据====",refObj.value)
console.log("JSON序列化拷贝====",JSON.parse(JSON.stringify(refObj.value)))
console.log("手写深拷贝====",deepCopy(refObj.value))


// 手写深拷贝
export function deepClone(obj) {
  //判断 传入对象 为 数组 或者 对象
  var result = Array.isArray(obj) ? [] : {};
  // for in 遍历
  for (var key in obj) {
    // 判断 是否 为自身 的属性值(排除原型链干扰)
    if (obj.hasOwnProperty(key)) {
      // 判断 对象的属性值 中 存储的 数据类型 是否为对象
      if (typeof obj[key] === 'object') {
        // 有可能等于 null
        if (obj[key] === null ) {
          result[key] = null
          continue  
        }
        // 递归调用
        result[key] = deepClone(obj[key]);   //递归复制
      } 
      // 不是的话 直接 赋值 copy
      else {
        result[key] = obj[key];
      }
    }
  }
  // 返回 新的对象
  return result;
}
</script>

结果

猿创征文|【vue3学习】vue3中实现深拷贝_第2张图片


❗特别注意!不能使用JS的自带APIstructuredClone() 会使得Vue 抛出报错,(目前不知道为什么无法使用,暂时记住不要使用即可)


上诉谈论 使用 了 ref 定义的响应式数据(引用数据类型)的深拷贝进行说明,同理对于 reactive 定义的响应式数据的 同样有效!!!

你可能感兴趣的:(Vue-3,学习,vue.js,javascript)