踩坑之深浅拷贝

65 阅读2分钟

用了TimePicker组件

<FormItem label="默认图像持续时间">
    <TimePicker v-model="basicInformation.defaultImageDuration" type="time"/>
</FormItem>

官方文档model-value类型要求

后端传递数据类型为Number,单位毫秒,ui展示需要00:00:00格式单位秒,于是使用使用下面方法转化

//毫秒=>HH:mm:ss
export function millisecondsToTime(milliseconds) {
    const totalSeconds = Math.floor(milliseconds / 1000);
    const hours = Math.floor(totalSeconds / 3600);
    const minutes = Math.floor((totalSeconds % 3600) / 60);
    const seconds = totalSeconds % 60;

    const formattedTime = `${String(hours).padStart(2, '0')}:${String(minutes).padStart(2, '0')}:${String(seconds).padStart(2, '0')}`;
    return formattedTime;
}
输出类型String

image.png 效果如下,此时也没有报类型错误

image.png

回传给后端为Number类,单位毫秒

export function timeStringToMilliseconds(timeString) {
    const [hours, minutes, seconds] = timeString.split(':').map(Number);
    const totalMilliseconds = (hours * 3600 + minutes * 60 + seconds) * 1000;
    return totalMilliseconds;
}
输出类型Number

image.png 一切看似没有任何问题,但是在点击保存时报错,报错

image.png

image.png 根据报错信息提示为组件类型问题,于是从新检查,在初始赋值是打印了赋完值后的类型,

console.log(typeof basicInformation.value.defaultImageDuration)
输出 String

说明组件类型是没有问题的,于是又使用{{}}看看在页面展示时值的类型

{{basicInformation.defaultImageDuration}}

同样为String,没有任何问题,,此时毫无头绪,于是就此搁置.....

在其他任务完成后,于是回过头来继续解决此问题

在之前错误提示里虽说String类型也可以,使用时也没有报错,但官方文档要求为Date 类型,那就按官方文档来吧,转换为Date 类型,但结果依旧如此,这就难搞了,就在百思不得其解时想到,突然想到会不会是在保存时改变了原组件值的类型导致的问题,于是声明变量赋值

image.png 但是结果依旧如此,但此时已经很接近答案了,又在百思不得其解一会后突然想到

这可能是由于浅拷贝引起的问题。在 Vue 中,如不使用深拷贝,只是引用了原始数据的地址,当修改副本时,也会影响原始数据。这导致了组件类型的错误。

于是立马使用 JSON 序列化和反序列化来深拷贝,果然这就是问题所在,到此成功解决!

image.png 总结:在回传给后端值时如果要改变组件值类型,需要深拷贝一层,不然在保存的一瞬间会污染原有值的类型导致组件报错!