大型表单冗余值踩坑记:我用一个组件,让表单项 “隐藏即重置”

25 阅读2分钟

前言

以巧妙设计,应对复杂场景,应对大型表单提交冗余值,靠 v-if 销毁组件的特性,在生命周期里自动重置无需填写的表单项 。

忙了一周,处理完工作上的需求,终于盼来能静心学习的周六。刚点开收藏的技术文档,屏幕右下角的企业微信突然弹出消息 —— 后端同事发来紧急疑问,用户详情页莫名多了个文件入口,是不是前端出问题了?

一瞬间,满心期待的安静被打乱,心里掠过一丝失落,却也只能无奈笑笑,关掉文档,指尖重新落回键盘,开始排查这个突如其来的 bug。

啪!总算揪出了问题根源 —— 后端用覆盖式更新存了所有传参,而前端没根据不同状态重置无用值,结果让些冗余数据 “漏” 到了页面上,闹了这么个小乌龙。

可一琢磨,头瞬间大了 —— 足足 130 多个表单项,还裹着 18 种组合类型!真要一个个手动处理,这得熬到猴年马月啊?

我盯着满屏的表单项代码犯愁 —— 既然每个表单项都是靠 v-if 控制显隐,那能不能让它们一隐藏,就自动把值清掉?v-if 切换显隐时会触发啥?啪!突然一拍脑门想起来了:众所周知 v-if 隐藏时会直接销毁组件啊!那岂不是能在组件销毁前,把对应的值都重置掉?

素材02.gif

解决思路

利用 v-if 会销毁组件的特性,使用生命周期来重置对应表单项的值,新建的一个名为 AutoResetFormItem 组件来代替 el-form-item,使用 v-bind="$attrs" 尽可能的不影响原来的 el-form-item

<script setup>
import { useTemplateRef, onBeforeUnmount } from 'vue';

defineOptions({ name: 'AutoResetFormItem' });

const formItemRef = useTemplateRef('formItem');

// 组件销毁之前重置表单项
onBeforeUnmount(() => formItemRef.value.resetField());
</script>

<template>
  <el-form-item ref="formItem" v-bind="$attrs">
    <slot />
  </el-form-item>
</template>

说干就干!我直接一键替换,把上次需求里所有用 el-form-item 的地方,全换成了 AutoResetFormItem。看着替换完成的提示,心里暗爽 —— 这下又能省下大把时间,不用吭哧吭哧手动改那些表单项了!

最后

不过这个 AutoResetFormItem 组件还藏了个小坑 —— 头疼的是,外部根本没法通过 ref 拿到 el-form-item 原本导出的那些属性和方法。我翻来覆去琢磨了半天,目前能想到的也就只有逐个手动导出这招了,也欢迎各位大佬不吝赐教,给指条更优的路子~