在 Vue3 的项目中使用了 JS 对象的 setter 和 getter 属性,打包后失效是怎么回事?
问题概述:
由于前端 Vue 组件需要绑定 v-model
的数据格式和接口返回和上传的格式不一样,为了方便使数据“双向同步”,我想到使用 JS 对象的 setter
和 getter
属性来实现,事实证明这也是很方便的.
一切在我本地开发时都正常,最近打包后发布在测试环境后发现出了 Bug,好像是 setter
和 getter
没有生效.
如果打包前正常,打包后出了 Bug 是不是打包这里出问题了呢,所以想问问有没有了解 Vue 和 Vite 打包机制的大佬,看能不能帮忙定位下问题.
开发环境:
使用了 Vue3 开发,并配套使用了 Vite.js 打包(被Vue主页各种忽悠使用的)
Vue 3.0.5
Vite 2.1.5
element-plus: ^1.0.2-beta.39
涉案代码:
组件使用了 ElementUI 的 time-picker
的 range
模式,v-model
需要绑定 Date
数组.
<el-form-item prop="_timeRange" label="营业时间:">
<el-time-picker is-range
v-model="localForm._timeRange"
range-separator="至" start-placeholder="开始时间"
end-placeholder="结束时间"
placeholder="选择时间范围">
</el-time-picker>
</el-form-item>
服务端返回和要求上传的数据格式中,这两个时间是两个字符串字段:
{
"openingTimeEnd": "string",
"openingTimeStart": "string"
}
于是我从服务端获取表单后,做了如下处理:
const localForm = {
...form,
set _timeRange(value) {
console.log(value)
this.openingTimeStart = moment(value[0]).format('YYYY-MM-DD HH:mm:ss')
this.openingTimeEnd = moment(value[1]).format('YYYY-MM-DD HH:mm:ss')
},
get _timeRange() {
this.openingTimeEnd = this.openingTimeEnd || "1949-10-01 17:00:00"
this.openingTimeStart = this.openingTimeStart || "1949-10-01 09:00:00"
return [new Date(this.openingTimeStart), new Date(this.openingTimeEnd)]
},
}
这样一来,每当修改 _timeRange
的时候,都会自动设置 localForm
中的 openingTimeStart
和 openingTimeEnd
字段.
这一效果在我本地调试时也是正常的,但打包后就失效了,表现为我设置时间后,openingTimeStart
和 openingTimeEnd
字段并不更新
请教!
这个 Bug 我没有头绪,难道要放弃这种思路,然后去监听事件手动修改字段吗,请大佬们不吝赐教
!
补充
在我本地调试时,打印我处理后的表单如下:
可以看到我设置的多个 set
和 get
打包后,打印的结果如下:
所有的 get
和 set
消失了!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
更新
在 Github 上找到了该 issue#3247,具体的原因如下:
Bug 原因
为了定位 Bug,我想到去查看打包后,代码到底发生了什么变化。阅读打包后的代码,我发现问题出在打包后,对 ES6 解构语法的转译,即对以下代码的转译:
打包过程中,会把以上涉及
...
解构符号的代码转化为一个函数,类似以下代码:(其中obj1
就是被解构的对象,obj2
就是把剩下的属性包装成一个对象)代码考虑了普通属性和
Symbols
属性,却没考虑setter
和getter
. 问题就出在这里,在for in
循环中,虽然_value
作为属性可以被拷贝,但无法拷贝他的getter
和setter
,这就导致了,_value
被拷贝后的值只是一个从obj2
中的setter
获取的一个静态值. 所以 bug 就出现了.解决办法
问题出现在打包时对
...
解构符的转译,那么可以避免在使用setter
和getter
的同时避免使用...
符号,可以避免该问题.但仍然感觉这应该是
vitejs
打包时的一个 Bug,不知道vite.js
底层使用了什么工具打包,还是自己新写的,总之应该被解决.Demo
根据边城的建议,我做了一个 bug 复现的Demo,(需要打包后才能复现 Bug)
其实原理上面应该介绍的差不多了,Demo 的关键代码如下: