表单禁用态切换引发el-cascader显示异常分析与解决
背景 & 问题
最近有一个需求用到了el-cascader,需要支持多级数据的选择。我们的产品,在进入表单编辑时,表单是默认禁用的,用户在需要编辑时需要点击一个按钮使得表单状态从禁用到可编辑。在这个过程注意到,el-cascader显示的ui会有错乱问题,具体表现如下图:
所选中的选项和当前el-cascader的长度相符时,会复现该问题。
el-cascader的代码如下:
<el-form-item label="国家或地区" :prop="`region_access_control.list.${idx}.country`" :rules="rules.country" class="access-control-item" > <el-cascader v-model="itm.country" :options="countryOptions" :props="{ expandTrigger: 'hover', multiple: true, emitPath: false }" :show-all-levels="false" style="width: 100%" clearable filterable > </el-cascader> </el-form-item>
问题分析 & 解决思路
遇到该问题时首先怀疑是el-cascader宽度不足的问题导致,但是后续分析了下,即使宽度再怎么调整,也会有所选中的选项和输入框长度相符的情况,所以这个想法作罢。
接着尝试在复现该问题的场景下,将一个已选中的选项取消勾选,再选中。注意到这时候el-cascader会重新触发标签宽度的计算,以及为选中的标签尾部增加 "x",此时怀疑是否是el-cascader内部更新样式的代码没有触发。于是去看了el-cascader的源码,发现内部实际上是通过这样一条链路去触发样式重新计算:
watch(disabled属性) -> 调用computePresentContent -> 调用computePresentTags
接着就尝试去验证这条链路上哪一步没有触发。首先打印出来computePresentContent
方法,并在浏览器中为其添加断点,然后尝试禁用/启用表单,发现没有触发该断点。尝试选中其他标签,可以触发断点。到这一步,怀疑是watch监听的disabled处就没有调用computePresentContent
方法。接着在源码中查找disabled
,发现这是一个prop
,需要主动传入。由于我们上面代码中没有传入这个prop,所以我们表单禁用/启用状态的变更就没有触发watch。
紧接着我就有一个疑问,为什么el-cascader在我没有传入disabled的时候,会跟随外层el-form的状态变更变得禁用或者可选择?
接着深入源码发现,el-cascader内部依赖了两个disabled,一个是我们传入disabled的,另一个是inject的elForm.disabled
。两者共同生效:
isDisabled() { return this.disabled || (this.elForm || {}).disabled; }
但是,后者并不会触发标签的重新计算。所以会出现上述的问题。至此问题已经很明了了,我们只需要将表单的外层控制表单组件的disabled也传入el-cascader中,就能在禁用状态变更时,重新计算标签高度。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· Obsidian + DeepSeek:免费 AI 助力你的知识管理,让你的笔记飞起来!
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
2022-01-23 Javascript高级程序设计第五章 | ch5 | 阅读笔记
2022-01-23 leetcode | 107. 二叉树的层序遍历 II | javascript实现 | c++实现
2022-01-23 Javascript高级程序设计第四章 | ch4 | 阅读笔记
2022-01-23 Javascript高级程序设计第三章 | ch3 | 阅读笔记
2022-01-23 Javascript高级程序设计第二章 | ch2 | 阅读笔记
2022-01-23 Javascript高级程序设计第一章 | ch1 | 阅读笔记