哎 又是屎山代码

前言:

大家都头疼屎山代码是个什么样子的,有什么特点?最突出的应该就是不易维护吧,别人看了后无限被吐槽的垃圾代码吧,这TM是什么意思?这怎么能改变?看不懂!完全看不懂,网上一直在说,当你写出这样的代码的时候,公司已经离不开你了,这只是一个梗,从开发的角度来看,我觉得优秀的代码还是必须的。

经历过N多的项目,每个项目都是N个人经手的,看过了太多人的代码,形形色色,我觉得这一次的代码应该算是比较经典的屎山代码了(难维护的代码)

正文开始:

这是一个表单提交的功能代码。

第一个表单提交完,点击下一步到下一个表单继续填写。

外层容器代码量:724行

主要代码:

sql 复制代码
<div class="body" ref="refScroll">      <info        ref="Ref1"        v-model="formData" // 注意看这        v-show="activeTab === tabList[0].value"        :isCheck="isCheck"        @emitChange="(data) => (formData = data)"        @emitOnNext="emitOnNext"        @emitOldFormData="(val) => (oldFormData = val)"      ></info>      <config        v-model="formData" // 注意看这        v-show="activeTab === tabList[1].value"        :isCheck="isCheck"        @emitChange="(data) => (formData = data)"      ></config>    </div>

上面代码经过一点修改,不影响后续说明,info组件表示信息表单内容,config组件表示设置表单的内容。

在两个表单中共同使用了formData的字段存储数据,在父组件中会监听到子组件的change事件即emitChange的事件,并修改formData的数据,父组件通过v-model来控制子组件里modelValue的字段

子组件代码:

两子组件代码量分别为:473行与800行

javascript 复制代码
watch(  () => props.modelValue,  (val) => {    console.log('props.modelValue', val, 'files');    formData.value = val;  });

在子组件中:info与config均有一样的代码,监听父组件props.modelValue,并重新赋值给子组件中定义的formData。

子组件中如何改变父组件的formData呢?

javascript 复制代码
watch(  formData.value,  (data, pre) => {    emit('emitChange', data);  },  {    deep: true,  });

在两个子组件中的表单中均有一样的代码,监听formData的变化,然后变化了会通知父组件改变formData。

好了上面逻辑讲差不多了。

不知道有没有大佬发现问题?

formData的数据流就会变成这样:

只要有一方formData更新变化了,就会影响其它两方的组件的数据更新。

bug来了:

由于这个页面是采用的keep-live的方式,就是说页面在退出的时候页面上的数据依然还是存在的。

父组件在再次进入的时候需要在onActivate的生命周期方法里重置表单的数据。

ini 复制代码
formData.value = {      ...initForm, // initForm为空值状态    };

我在所有能改变formData的地方一个一个排查一个一个加上console,于是便有下面的打印,

两个子组件 config与info,在再次进入的时候,页面先走了父组件的onActivate的方法,重置了父组件的formData,但是在两个子组件中不知道哪一个触发了自己内部的formData的更新(此时还是老的formData),向父组件发射了老的formData数据,进而导致父组件的formData的数据再次被更新,最终引起页面还是用了老的数据。

排查:

于是就要是排除是哪个子组件引起了更新:

在两个子组件里看到了很多与formDate绑定的v-model,即每个输入项都绑定了v-model,这就给排查造就了很大的困难。

虽然最后也找到了哪个组件触发的重新赋值更新,但是已经没什么意义了,这块代码已经动不了了,能做的只有在其基础上不断修复,基础代码已经定型,除非全部整改。

修改后的代码,很简单

ini 复制代码
nextTick(() => {      formData.value = {        ...initForm,      };    });

上图说明在首次进入的时候会先触发子组件formData的更新,接着父组件会触发formData的更新覆盖。

写在最后

为什么说屎山代码?像这种问题被抛出没有一定经验能力其实是非常难排查的,因为在formData已经不是单纯的双向流了,已经进阶到了3向流,子组件里还有各种双向流,写的时候是挺爽的,后续问题出来了,改的时候是真心疼,组件值重复修改,如果放到react,估计就会有性能问题了

相关推荐
子兮曰4 天前
jev-ultrafast 深度解析:7 秒订机票的浏览器 Agent 是如何炼成的
前端·后端·agent
子兮曰4 天前
Jev 爆发一周:7 秒 Agent 背后的 System One 生态与三场争议
前端·后端·ai编程
前端小万4 天前
写公众号赚了 3000 块后,我做了一款叫 "一键成稿" 的软件
前端·微信小程序
爱勇宝4 天前
ZCode 开源 24 小时:一份没有历史的账本,回答不了"有没有偷代码"
前端·后端·chatglm (智谱)
三十而立洋4 天前
Cookie 详解:从产生到安全,一次讲透
前端·javascript
卡布鲁4 天前
把一个 Vite + Vue3 应用塞进 qiankun (React + Umi3) 主站:十个坑的复盘
前端·javascript·react.js
汉堡大王95274 天前
Jev:不是聊天机器人, 而是一个智能 if 语句
前端·人工智能·后端
梦想很大很大4 天前
从运行事实到回归证据:Workrun 的 Telemetry 与 Evaluation 实践
前端·人工智能·后端
计算机魔术师4 天前
Meta Muse agent 接入 Shopify 的 Shop Pay 实现代理式购物
前端
沙蒿同学4 天前
我用 Go 搭了一条 AI Agent 流水线:从 1 张商品图到一整套淘宝详情页
前端·javascript·后端