vue递归深拷贝

vue2低轨写法

   deepClone(obj, cache = new WeakMap()) {
      if (obj === null || typeof obj !== "object") return obj;
      if (obj instanceof Date) return new Date(obj);
      if (obj instanceof RegExp) return new RegExp(obj);

      if (cache.has(obj)) return cache.get(obj); // 如果出现循环引用,则返回缓存的对象,防止递归进入死循环
      let cloneObj = new obj.constructor(); // 使用对象所属的构造函数创建一个新对象
      cache.set(obj, cloneObj); // 缓存对象,用于循环引用的情况

      for (let key in obj) {
        if (obj.hasOwnProperty(key)) {
          cloneObj[key] = this.deepClone(obj[key], cache); // 递归拷贝
        }
      }
      return cloneObj;
    },



//使用方法
click(){
    const newObj = this.deepClone(oladObj);
    console.log(newObj == oladObj); // false
}

vue3写法

  /////////////递归深拷贝
    const deepClone = (obj, cache = new WeakMap()) => {
      if (obj === null || typeof obj !== "object") return obj;
      if (obj instanceof Date) return new Date(obj);
      if (obj instanceof RegExp) return new RegExp(obj);

      if (cache.has(obj)) return cache.get(obj); // 如果出现循环引用,则返回缓存的对象,防止递归进入死循环
      let cloneObj = new obj.constructor(); // 使用对象所属的构造函数创建一个新对象
      cache.set(obj, cloneObj); // 缓存对象,用于循环引用的情况

      for (let key in obj) {
        if (obj.hasOwnProperty(key)) {
          cloneObj[key] = deepClone(obj[key], cache); // 递归拷贝
        }
      }
      return cloneObj;
    };


//使用方法
    const objclick = () => {
      const newObj = deepClone(oladObj);
      console.log(newObj == oladObj); // false
    };


    return {

         objclick,

     }   

<think>我们被要求提供Vue3中深拷贝的实现方法。根据引用[1]和引用[2],我们可以知道在Vue3中,直接对响应式对象进行深拷贝会失去响应式。因此,深拷贝通常用于需要静态数据副本的场景。在Vue3中实现深拷贝的常见方法有两种:1.使用JSON序列化:`JSON.parse(JSON.stringify(obj))`2.使用递归函数进行深拷贝(如引用[2]中的工具函数)同时,引用[2]提供了一个工具函数`deepClone`,它可以处理数组、对象和其他基本类型,并且能够判断对象的数据类型。因此,我们可以提供以下解决方案:方法一:使用JSON序列化-优点:简单快捷-缺点:无法处理函数、undefined、循环引用和特殊对象(如Date,RegExp等)方法二:使用递归深拷贝函数(如引用[2]中的工具函数)-优点:可以处理更多类型(但引用[2]中的函数对于Date、RegExp等类型实际上并没有特殊处理,而是直接返回,因此这些特殊对象会被浅拷贝,需要改进才能深拷贝)-缺点:需要手动实现,且处理循环引用较复杂另外,我们还可以考虑使用第三方库,比如lodash的`_.cloneDeep`,它提供了更完善的深拷贝功能。根据用户需求,我们提供两种实现方式,并给出改进的深拷贝函数(处理Date、RegExp等常见内置对象)。注意:由于深拷贝会失去响应式,所以拷贝后的对象不再与Vue的响应式系统关联。步骤:1.实现一个更完善的深拷贝函数,能够处理Date、RegExp、Array、Object等。2.说明在Vue3中如何使用。考虑到引用[3]提到了以插件方式封装公共方法,我们也可以将深拷贝函数封装为Vue3的全局属性或通过provide/inject使用,或者直接作为工具函数导入。下面给出具体代码:</think>### Vue3 中实现深拷贝的完整指南 在 Vue3 中实现深拷贝时,关键要理解**响应式系统特性**:深拷贝会剥离对象的响应式特性,拷贝后的对象不再触发视图更新。以下是三种实现方法: #### 方法一:JSON 序列化(简单场景) ```javascript import { reactive } from 'vue'; const original = reactive({ user: { name: 'Alice', roles: ['admin'] }, created: new Date() }); // ✅ 深拷贝实现 const copy = JSON.parse(JSON.stringify(original)); // ⚠️ 注意: // 1. 会丢失 Date/RegExp 等特殊对象类型(转为字符串) // 2. 忽略 undefined 和函数属性 // 3. 无法处理循环引用 ``` #### 方法二:递归深拷贝函数(推荐) ```javascript // 工具函数 utils/clone.js export function deepClone(source) { if (source === null || typeof source !== 'object') { return source; } // 处理特殊对象 if (source instanceof Date) return new Date(source); if (source instanceof RegExp) return new RegExp(source); const clone = Array.isArray(source) ? [] : {}; for (const key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { clone[key] = deepClone(source[key]); } } return clone; } // Vue3 组件中使用 import { reactive } from 'vue'; import { deepClone } from '@/utils/clone'; const state = reactive({ data: { /*...*/ } }); const staticCopy = deepClone(state.data); // ✅ 完全解耦的深拷贝 ``` #### 方法三:第三方库(复杂对象) ```bash npm install lodash.clonedeep ``` ```javascript import { reactive } from 'vue'; import cloneDeep from 'lodash.clonedeep'; const original = reactive({ nested: { map: new Map([['key', 'value']]) } }); const copy = cloneDeep(original); // ✅ 支持 Map/Set 等复杂类型 ``` #### 💡 关键注意事项: 1. **响应式丢失** 深拷贝后的对象与原始响应式对象完全解耦,修改拷贝对象不会触发视图更新[^1] 2. **性能优化** 对于大型对象,使用 Web Worker 进行异步克隆: ```javascript // worker.js self.onmessage = (e) => { const clone = JSON.parse(JSON.stringify(e.data)); postMessage(clone); }; // 组件中 const worker = new Worker('@/utils/clone.worker.js'); worker.postMessage(largeObject); worker.onmessage = (e) => setStaticCopy(e.data); ``` 3. **循环引用处理** 增强版深拷贝支持循环引用: ```javascript export function deepCloneWithRefs(source, cache = new WeakMap()) { if (cache.has(source)) return cache.get(source); // ...其他类型处理逻辑同上 const clone = Array.isArray(source) ? [] : {}; cache.set(source, clone); // 缓存引用 for (const key in source) { clone[key] = deepCloneWithRefs(source[key], cache); } return clone; } ``` #### 最佳实践场景: | 场景 | 推荐方法 | 原因 | |------|----------|------| | 表单初始值 | `JSON.parse(JSON.stringify())` | 简单快速 | | 状态快照 | 递归深拷贝函数 | 保留日期等类型 | | 复杂对象 | Lodash.cloneDeep | 支持 Map/Set 等 | | 性能敏感 | Web Worker + 结构化克隆 | 避免主线程阻塞 | > **何时需要深拷贝**:当您需要完全独立的数据快照(如历史记录、撤销操作、静态报表导出)时使用[^2]。对于需要保持响应式的场景,应使用 `reactive({ ...original })` 进行浅层响应式复制。 ### 封装为 Vue3 插件 参考引用[3],可全局注册深拷贝方法: ```javascript // plugins/deepClone.js import { deepClone } from '@/utils/clone'; export default { install(app) { app.config.globalProperties.$deepClone = deepClone; } }; // main.js import { createApp } from 'vue'; import deepClonePlugin from './plugins/deepClone'; const app = createApp(App); app.use(deepClonePlugin); // 组件中使用 const copy = this.$deepClone(reactiveObj); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值