本文将详细讲解三种vue深拷贝的实现方式,分别为递归实现、JSON.parse/stringify、lodash库实现。下面将分为以下几个部分来介绍。
1. 递归实现
递归实现是一种最简单的深拷贝方式,其代码实现如下:
function deepClone(obj) {
if (obj === null || typeof obj !== "object") {
return obj;
}
const newObj = Array.isArray(obj) ? [] : {};
for (let key in obj) {
newObj[key] = deepClone(obj[key]);
}
return newObj;
}
该函数的参数obj为需要进行深拷贝的对象,如果该对象是基本类型或为null,直接返回即可。如果是数组或对象,则进行遍历并递归调用deepClone函数。
该方法的优点是实现简单易懂,缺点是递归耗费性能,在深度较大的对象或数组时可能会导致栈溢出的问题。
下面是一个示例:
<button @click="cloneObj">click me</button>
<div v-for="(item, index) in obj" :key="index">{{item}}</div>
export default {
data() {
return {
obj: {
name: "Tom",
age: 18,
friends: ["Jerry", "Jack"],
address: {
city: "New York",
district: "Manhattan",
},
},
};
},
methods: {
cloneObj() {
const newObj = deepClone(this.obj);
newObj.name = "Lucy";
newObj.friends.push("Lily");
newObj.address.city = "San Francisco";
this.obj = newObj;
},
},
};
在上面示例中,当我们点击按钮触发cloneObj函数时,会将原对象深拷贝一份,并修改其中的内容并将其赋值给data中的obj。当页面重新渲染时,我们可以看到原对象并未被修改。
2. JSON.parse/stringify
第二种实现方式是通过JSON.parse和JSON.stringify方法来实现深拷贝,如下所示:
function deepClone(obj) {
return JSON.parse(JSON.stringify(obj))
}
该方法的优点是效率较高,而且可以处理对象中的函数、undefined等类型,不会受栈的限制。但是该方法有一些缺点,比如当对象中存在循环引用时,会导致函数陷入死循环,并且对于日期、正则表达式等类型的数据无法处理,会被转化成字符串。
下面是一个示例:
<button @click="cloneObj">click me</button>
<div v-for="(item, index) in obj" :key="index">{{item}}</div>
export default {
data() {
return {
obj: {
name: "Tom",
age: 18,
friends: ["Jerry", "Jack"],
address: {
city: "New York",
district: "Manhattan",
},
},
};
},
methods: {
cloneObj() {
const newObj = deepClone(this.obj);
newObj.name = "Lucy";
newObj.friends.push("Lily");
newObj.address.city = "San Francisco";
this.obj = newObj;
},
},
};
通过上面的示例我们可以看到,当我们点击按钮触发cloneObj函数时,透过JSON.parse和JSON.stringify我们可以顺利地将原对象进行深拷贝,同样也能成功修改其中的内容并将其赋值给data中的obj。而在页面重新渲染时,我们仍可看到原对象并未被修改。
3. lodash库实现
第三种实现方式是通过使用lodash库中的cloneDeep方法来实现深拷贝,如下所示:
import cloneDeep from 'lodash/cloneDeep'
const newObj = cloneDeep(oldObj)
该方法的编写方式相对较简单,使用的方法也非常简洁,且能处理循环引用问题。但是需要注意该方法要消耗更多的性能资源,也需要引入lodash库。
下面是一个示例:
<button @click="cloneObj">click me</button>
<div v-for="(item, index) in obj" :key="index">{{item}}</div>
// 首先需要安装lodash依赖,在终端中输入 npm install lodash -S
import cloneDeep from 'lodash/cloneDeep'
export default {
data() {
return {
obj: {
name: "Tom",
age: 18,
friends: ["Jerry", "Jack"],
address: {
city: "New York",
district: "Manhattan",
},
},
};
},
methods: {
cloneObj() {
const newObj = cloneDeep(this.obj);
newObj.name = "Lucy";
newObj.friends.push("Lily");
newObj.address.city = "San Francisco";
this.obj = newObj;
},
},
};
在上面示例中,我们可以看到当我们点击按钮触发cloneObj函数时,通过lodash.library库中的cloneDeep方法我们可以顺利地进行深拷贝,并成功修改其中的内容并将其赋值给data中的obj。当页面重新渲染时,我们同样可以看到原对象并未被修改。
总结
到此,我们就完成了vue深拷贝的三种实现方式的攻略,它们分别为递归实现、JSON.parse/stringify、lodash库实现。不同的实现方式针对不同的场景有着各自的优缺点,请根据具体的情况合理选择深拷贝方式。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:vue深拷贝的3种实现方式小结 - Python技术站