Open gogoend opened 4 years ago
这里是我根据网上找的资料写出的递归深拷贝的方法。
o是原始对象,newO是目标对象。
逻辑大致是,通过原始对象o的key,访问对象中的value。
如果value是数组或是对象,那就新定义一个临时容器,存储将会访问的数组或对象中的值。递归调用这个函数,访问value中的内容,赋值给临时容器。
否则(如果value是基本数据类型)就直接将值赋值给目标对象对应的key。
function deepCopy(o, newO) {
for (let key in o) {
if (o[key] instanceof Object) {
let tempO = o.constructor === Array ? [] : {}
deepCopy(o[key], tempO)
newO[key] = tempO
} else {
newO[key] = o[key]
}
}
}
(完了我其实已经晕了)
背景
近日做公司的一个Vue.js项目的时,需要这样一个需求:在页面上的选项卡切换后,再返回当前选项卡,需保留选项卡的状态,例如选项卡里表单中的值。
事实上,这样的需求,可以直接用v-show,或者keep-alive来实现。
无奈之前甲方要求过于急躁,而iView组件的选项卡实在弄不出来,有Bug(所以我并不是很信任别人的组件),keep-alive之前我也没用过,所以只好自己以最笨的方法实现了一个选项卡。
最终选项卡渲染以后,选项卡上方标签使用v-for遍历有多个,下方选项卡组件只有一个 —— 标签页的切换实质上是数据的回填过程;为保存当前选项卡的数据,使得切换回来后能够回填数据,需要对数据进行一次深拷贝进行存储。
之前拷贝使用的是超级常用的JSON序列化反序列化。
在对日期进行操作的时候,发生了一些错误:
JSON序列化反序列化日期时,执行了Date的toJSON方法,最终拷贝到的日期是一个字符串;回填数据的时候,将日期字符串进行分割(
.split('T')[0]
),取到前部分年月日(iview日期选择器不会进行判断),此时由于时区问题,时间向前减了一天,每次切换,回填一次,就减去一天。例如,现在是北京时间2020年5月22日
若按照这种方式取得年月日,最终取得的时间是2020年5月21日
由此可见,JSON序列化反序列化的深拷贝在遇到日期等复杂对象时,会变得不再可靠。