最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Vue中深克隆的3種實現(xiàn)方案

 更新時間:2026年04月28日 08:30:35   作者:前端那點(diǎn)事  
本文介紹了三種Vue開發(fā)中常用的深克隆實現(xiàn)方法,分別適用于不同場景,方案一適用于普通對象和數(shù)組,方案二適用于所有數(shù)據(jù)類型,方案三專門適配Vue的響應(yīng)式數(shù)據(jù),每種方案都有其優(yōu)點(diǎn)和缺點(diǎn),開發(fā)時可根據(jù)具體需求選擇合適的的方法,提高開發(fā)效率,需要的朋友可以參考下

深克?。ㄉ羁截悾┑暮诵氖?strong>復(fù)制一個對象/數(shù)組,且拷貝后的對象與原對象完全獨(dú)立,修改拷貝對象不會影響原對象(包括嵌套層級的屬性/元素)。在Vue開發(fā)中,深克隆常用于處理響應(yīng)式數(shù)據(jù)(如ref、reactive創(chuàng)建的數(shù)據(jù)),避免因淺拷貝導(dǎo)致的響應(yīng)式異常,以下是3種實用實現(xiàn)方案,從簡單到完善,覆蓋不同場景。

一、核心前提:淺克隆 vs 深克?。ū囟畢^(qū)別)

先明確淺克隆與深克隆的差異,避免混淆:

  • 淺克隆:僅復(fù)制對象的第一層屬性,嵌套的對象/數(shù)組仍指向原引用(修改嵌套內(nèi)容會影響原對象),如Object.assign()、擴(kuò)展運(yùn)算符(...)。
  • 深克?。簭?fù)制對象的所有層級(包括嵌套的對象、數(shù)組、函數(shù)等),拷貝后與原對象完全脫離引用,互不影響(這是Vue開發(fā)中常用的方式)。

Vue中注意點(diǎn):對于reactive創(chuàng)建的響應(yīng)式對象,直接克隆會丟失響應(yīng)式特性,需特殊處理;ref對象需先獲取.value再克隆。

二、方案1:基礎(chǔ)版深克?。ㄟm配普通對象/數(shù)組,無復(fù)雜類型)

適用于:普通對象、數(shù)組,無函數(shù)、Date、RegExp等復(fù)雜類型,代碼簡潔,上手快。

核心邏輯:利用JSON.stringify()將對象轉(zhuǎn)為字符串,再用JSON.parse()轉(zhuǎn)回對象,實現(xiàn)深度拷貝(本質(zhì)是序列化+反序列化)。

// 基礎(chǔ)版深克?。╒ue中可直接使用,適配簡單數(shù)據(jù))
function deepCloneBasic(obj) {
  // 處理null和非對象/數(shù)組類型(直接返回,無需克?。?
  if (obj === null || typeof obj !== 'object') {
    return obj;
  }
  // 利用JSON序列化+反序列化實現(xiàn)深克隆
  return JSON.parse(JSON.stringify(obj));
}

// Vue中測試示例(普通數(shù)據(jù))
const obj = { name: 'Vue', info: { version: '3.4.21' }, list: [1, 2, 3] };
const cloneObj = deepCloneBasic(obj);

// 修改拷貝對象,原對象不受影響
cloneObj.info.version = '3.5.0';
cloneObj.list.push(4);
console.log(obj.info.version); // 3.4.21(原對象不變)
console.log(obj.list); // [1,2,3](原對象不變)

優(yōu)點(diǎn):代碼簡潔,無需復(fù)雜邏輯,適配大部分簡單場景;

缺點(diǎn):無法克隆函數(shù)、Date、RegExp、undefined、Symbol等復(fù)雜類型(會丟失或變形),不適合包含這些類型的數(shù)據(jù)。

三、方案2:完善版深克隆(適配所有類型,通用推薦)

適用于:所有數(shù)據(jù)類型(對象、數(shù)組、函數(shù)、Date、RegExp等),解決基礎(chǔ)版的缺陷,是Vue開發(fā)中最常用的通用方案。

核心邏輯:遞歸遍歷對象/數(shù)組,對不同類型的數(shù)據(jù)分別處理,確保所有層級都被深度拷貝,不丟失類型和屬性。

// 完善版深克隆(適配所有類型,Vue通用)
function deepClonePerfect(obj) {
  // 1. 處理null和非對象類型(直接返回)
  if (obj === null || typeof obj !== 'object') {
    return obj;
  }

  // 2. 處理Date類型(避免Date被轉(zhuǎn)為普通對象)
  if (obj instanceof Date) {
    return new Date(obj);
  }

  // 3. 處理RegExp類型(保留正則的修飾符)
  if (obj instanceof RegExp) {
    return new RegExp(obj.source, obj.flags);
  }

  // 4. 處理數(shù)組和對象(區(qū)分?jǐn)?shù)組和普通對象)
  // 創(chuàng)建一個與原對象類型一致的空容器(數(shù)組→數(shù)組,對象→對象)
  const cloneObj = Array.isArray(obj) ? [] : {};

  // 5. 遞歸遍歷所有屬性,深度拷貝
  for (let key in obj) {
    // 只拷貝對象自身的屬性(排除原型鏈上的屬性)
    if (obj.hasOwnProperty(key)) {
      // 遞歸克隆子屬性(嵌套對象/數(shù)組)
      cloneObj[key] = deepClonePerfect(obj[key]);
    }
  }

  return cloneObj;
}

// Vue中測試示例(復(fù)雜數(shù)據(jù))
const complexObj = {
  name: '深克隆',
  date: new Date(),
  reg: /vue/g,
  func: () => console.log('vue'),
  info: { a: 1, b: { c: 2 } },
  list: [1, [2, 3]]
};

const cloneComplex = deepClonePerfect(complexObj);
cloneComplex.info.b.c = 100;
cloneComplex.list[1].push(4);
cloneComplex.date.setFullYear(2025);

console.log(complexObj.info.b.c); // 2(原對象不變)
console.log(complexObj.list[1]); // [2,3](原對象不變)
console.log(complexObj.date.getFullYear()); // 2024(原對象不變)
console.log(cloneComplex.func()); // vue(函數(shù)正常克?。?

優(yōu)點(diǎn):適配所有數(shù)據(jù)類型,克隆徹底,無數(shù)據(jù)丟失,滿足Vue中復(fù)雜數(shù)據(jù)的克隆需求;

缺點(diǎn):代碼稍復(fù)雜,無需額外依賴,可直接封裝到Vue項目中復(fù)用。

四、方案3:Vue專屬深克?。ㄟm配響應(yīng)式數(shù)據(jù),推薦)

適用于:Vue2/Vue3的響應(yīng)式數(shù)據(jù)(ref、reactive創(chuàng)建的數(shù)據(jù)),解決“克隆后丟失響應(yīng)式”的問題,結(jié)合Vue內(nèi)置API,更貼合Vue開發(fā)場景。

核心邏輯:利用Vue內(nèi)置的reactive、ref API,克隆后重新創(chuàng)建響應(yīng)式對象,確??寺『蟮臄?shù)據(jù)仍保持響應(yīng)式特性。

1. Vue3 專屬實現(xiàn)(適配ref、reactive)

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

// Vue3專屬深克隆(保留響應(yīng)式)
function deepCloneVue3(obj) {
  // 處理ref對象:先獲取原始值,克隆后重新創(chuàng)建ref
  if (isRef(obj)) {
    const rawValue = toRaw(obj.value); // 轉(zhuǎn)為原始值(避免響應(yīng)式干擾)
    const cloneValue = deepClonePerfect(rawValue); // 用完善版克隆原始值
    return ref(cloneValue); // 重新創(chuàng)建ref,保留響應(yīng)式
  }

  // 處理reactive對象:先獲取原始值,克隆后重新創(chuàng)建reactive
  if (isReactive(obj)) {
    const rawObj = toRaw(obj); // 轉(zhuǎn)為原始對象
    const cloneObj = deepClonePerfect(rawObj); // 深度克隆
    return reactive(cloneObj); // 重新創(chuàng)建reactive,保留響應(yīng)式
  }

  // 非響應(yīng)式數(shù)據(jù),直接用完善版克隆
  return deepClonePerfect(obj);
}

// 測試示例
const reactiveObj = reactive({ name: 'Vue3', info: { age: 5 } });
const refObj = ref({ a: 1, b: [2, 3] });

// 克隆響應(yīng)式數(shù)據(jù)
const cloneReactive = deepCloneVue3(reactiveObj);
const cloneRef = deepCloneVue3(refObj);

// 修改克隆對象,原對象不受影響,且克隆對象仍有響應(yīng)式
cloneReactive.info.age = 10;
cloneRef.value.b.push(4);

console.log(reactiveObj.info.age); // 5(原對象不變)
console.log(refObj.value.b); // [2,3](原對象不變)
console.log(cloneReactive.info.age); // 10(克隆對象響應(yīng)式正常)
</script>

2. Vue2 專屬實現(xiàn)(適配data、ref、reactive)

// Vue2專屬深克隆(保留響應(yīng)式,需引入Vue)
import Vue from 'vue'

function deepCloneVue2(obj) {
  // 處理Vue2的響應(yīng)式對象(data中定義的對象、Vue.observable創(chuàng)建的對象)
  if (Vue.isReactive(obj) || Vue.isVue(obj)) {
    // 用Vue.extend創(chuàng)建臨時組件,通過props傳遞數(shù)據(jù),實現(xiàn)響應(yīng)式克隆
    const TempComponent = Vue.extend({
      props: Object.keys(obj),
      render: function() {}
    });
    const instance = new TempComponent({ propsData: obj });
    return instance._props;
  }

  // 處理ref對象(Vue2的ref需通過.value訪問)
  if (obj && obj._isRef) {
    const cloneValue = deepClonePerfect(obj.value);
    return Vue.ref(cloneValue);
  }

  // 非響應(yīng)式數(shù)據(jù),用完善版克隆
  return deepClonePerfect(obj);
}

// 測試示例(Vue2)
const vue2Reactive = Vue.observable({ name: 'Vue2', list: [1, 2] });
const cloneVue2 = deepCloneVue2(vue2Reactive);
cloneVue2.list.push(3);
console.log(vue2Reactive.list); // [1,2](原對象不變)
console.log(cloneVue2.list); // [1,2,3](克隆對象響應(yīng)式正常)

優(yōu)點(diǎn):專門適配Vue響應(yīng)式數(shù)據(jù),克隆后不丟失響應(yīng)式特性,貼合Vue開發(fā)場景;

缺點(diǎn):依賴Vue內(nèi)置API,需區(qū)分Vue2和Vue3版本。

五、Vue中深克隆的注意事項

  • 克隆響應(yīng)式數(shù)據(jù)時,不可直接用基礎(chǔ)版(JSON方式),會丟失響應(yīng)式特性,需用Vue專屬方案;
  • Vue3中,reactive對象克隆前需用toRaw()轉(zhuǎn)為原始對象,否則會因響應(yīng)式代理導(dǎo)致克隆異常;
  • 避免克隆Vue組件實例、Vuex狀態(tài)等特殊對象,這類對象克隆后可能無法正常使用;
  • 若項目中頻繁使用深克隆,可將完善版/Vue專屬版封裝為全局工具函數(shù)(如utils/clone.js),方便復(fù)用;
  • 簡單場景(無復(fù)雜類型、非響應(yīng)式數(shù)據(jù))可直接用基礎(chǔ)版,復(fù)雜場景優(yōu)先用完善版,響應(yīng)式數(shù)據(jù)用Vue專屬版。

六、總結(jié)(方案選擇建議)

  1. 簡單場景(普通對象/數(shù)組,無復(fù)雜類型):方案1(基礎(chǔ)版),簡潔高效;
  2. 通用場景(所有數(shù)據(jù)類型,非響應(yīng)式):方案2(完善版),克隆徹底,無數(shù)據(jù)丟失;
  3. Vue開發(fā)場景(響應(yīng)式數(shù)據(jù)):方案3(Vue專屬版),保留響應(yīng)式,貼合Vue特性。

實際開發(fā)中,可根據(jù)數(shù)據(jù)類型和是否為響應(yīng)式,選擇對應(yīng)的方案,建議將方案2和方案3封裝為全局工具,提升開發(fā)效率。

以上就是Vue中深克隆的3種實現(xiàn)方案的詳細(xì)內(nèi)容,更多關(guān)于Vue深克隆實現(xiàn)方案的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Vue渲染函數(shù)詳解

    Vue渲染函數(shù)詳解

    下面小編就為大家?guī)硪黄猇ue渲染函數(shù)詳解。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-09-09
  • Nuxt.js 靜態(tài)資源和打包的操作

    Nuxt.js 靜態(tài)資源和打包的操作

    這篇文章主要介紹了Nuxt.js 靜態(tài)資源和打包的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-11-11
  • Vue實現(xiàn)微信支付功能遇到的坑

    Vue實現(xiàn)微信支付功能遇到的坑

    這篇文章主要介紹了Vue實現(xiàn)微信支付功能遇到的坑,本文是小編記錄整理下拉的,以便日后所需,需要的朋友可以參考下
    2019-06-06
  • 詳解Vue3的響應(yīng)式原理解析

    詳解Vue3的響應(yīng)式原理解析

    這篇文章主要為大家介紹了Vue3的響應(yīng)式原理解析,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2021-12-12
  • 手把手教你創(chuàng)建vue3項目的最佳方式

    手把手教你創(chuàng)建vue3項目的最佳方式

    如今的Vue3已經(jīng)勢不可擋,當(dāng)然搭建一個全新的Vue3項目也有了全新的方式,下面這篇文章主要給大家介紹了關(guān)于如何手把手教你創(chuàng)建vue3項目的最佳方式,文中通過實例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-11-11
  • SpringBoot實現(xiàn)全局和局部跨域的兩種方式

    SpringBoot實現(xiàn)全局和局部跨域的兩種方式

    本文主要介紹了SpringBoot實現(xiàn)全局和局部跨域的兩種方式,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-01-01
  • vue路由插件之vue-route

    vue路由插件之vue-route

    這篇文章主要介紹了vue路由插件之vue-route的相關(guān)知識,本文通過實例代碼給大家介紹了vue router的使用,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下
    2019-06-06
  • Vue利用vue-baidu-map實現(xiàn)獲取經(jīng)緯度和搜索地址

    Vue利用vue-baidu-map實現(xiàn)獲取經(jīng)緯度和搜索地址

    在開發(fā)項目的時候,發(fā)現(xiàn)需要獲取經(jīng)緯度,由于這個項目是用vue寫的,最后決定使用vue-baidu-map來快速獲取經(jīng)緯度,感興趣的可以了解一下
    2022-09-09
  • Vue中使用v-print打印出現(xiàn)空白頁問題及解決

    Vue中使用v-print打印出現(xiàn)空白頁問題及解決

    這篇文章主要介紹了Vue中使用v-print打印出現(xiàn)空白頁問題及解決方案,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-09-09
  • vue-cli創(chuàng)建項目及項目結(jié)構(gòu)解析

    vue-cli創(chuàng)建項目及項目結(jié)構(gòu)解析

    上一篇我們安裝了vue-cli,接下來我們就使用該腳手架進(jìn)行創(chuàng)建項目,這篇文章主要介紹了vue-cli創(chuàng)建項目以及項目結(jié)構(gòu)的相關(guān)資料,需要的朋友可以參考下面文章的具體內(nèi)容
    2021-10-10

最新評論

剑阁县| 贵定县| 永州市| 雷州市| 海晏县| 正蓝旗| 通化县| 林口县| 江川县| 青州市| 古田县| 囊谦县| 饶平县| 贡觉县| 米脂县| 宁河县| 三原县| 元氏县| 视频| 蓝山县| 武乡县| 吴忠市| 温州市| 辉南县| 固阳县| 光泽县| 承德县| 任丘市| 东乌珠穆沁旗| 澄迈县| 上林县| 徐州市| 龙门县| 庄浪县| 华宁县| 闽侯县| 来安县| 望城县| 颍上县| 柏乡县| 民乐县|