因el-col布局引起的表单项无法点击的问题

it2026-02-16  6

问题缘由

近日需要开发一个双列的表单编辑页面,伪页面如下: 简单思索后决定使用el-col控制表单项宽度以达到双列的效果

问题出现

由于难度不大,三下五除二就搞定了,伪代码如下:

<el-form :model="edit.data" label-width="100px"> <el-col :span="12"> <el-form-item prop="name" label="用户名: "> <el-input v-model="edit.data.name" placeholder="请输入用户名"></el-input> </el-form-item> </el-col> <el-col :span="12"> <el-form-item prop="type" label="账户类型: "> <el-select v-model="edit.data.type" placeholder="请选择账户类型" style="width: 100%;"> <el-option v-for="(item,index) in dict.types" :key="index" :label="item.label" :value="item.value"> </el-option> </el-select> </el-form-item> </el-col> <el-form-item prop="remark" label="备注: "> <el-input type="textarea" v-model="edit.data.remark" placeholder="请输入备注信息"></el-input> </el-form-item> </el-form>

[嘴角疯狂上扬] 然鹅,就在此时,问题出现了, 用户名输入框和账号类型下拉项无法点击的问题 具体大家可以到 el-form-item因el-col布局引起的部分表单项无法点击的问题的第一个表单中体验下

问题解决

首先通过百度找到了如下解决方案:vue+element UI中布局组件el-col和表单组件el-form组合使用时表单无法获取焦点 但是这里只说不能混用,那么真的不能混用吗?原因到底是为什么呢?

首先,通过浏览器控制台调试,发现将el-col的float:left样式取消后就正常了,如下图: 然鹅,这样虽说解决了不能点击的问题,但是一个表单项就占了一行,显然是不符合需求的,于是自作聪明,添加了如下样式:

.el-col { float: none; display: inline-block; }

嗯…问题解决了,但是这样的解决方案也不太优雅

继续找问题原因,当时写了这样一个表单,发现表单项是可以正常的点击的:

<el-form :model="edit.data" label-width="100px"> <el-col :span="12"> <el-form-item prop="name" label="用户名: "> <el-input v-model="edit.data.name" placeholder="请输入用户名"></el-input> </el-form-item> </el-col> <el-col :span="12"> <el-form-item prop="type" label="账户类型: "> <el-select v-model="edit.data.type" placeholder="请选择账户类型" style="width: 100%;"> <el-option v-for="(item,index) in dict.types" :key="index" :label="item.label" :value="item.value"> </el-option> </el-select> </el-form-item> </el-col> </el-form>

这和上面的表单不就差了一个字段吗?为什么加上remark的表单项之后就不行了呢? 比较两段代码,发现name和type的表单项的级次是三级,而remark的表单项的级次是二级,那么问题是不是出在了dom的层次结构上呢? 有此想法,在remark表单项外层加了个el-col,发现可以正常点击了,伪代码如下:

<el-form :model="edit.data" label-width="100px"> <el-col :span="12"> <el-form-item prop="name" label="用户名: "> <el-input v-model="edit.data.name" placeholder="请输入用户名"></el-input> </el-form-item> </el-col> <el-col :span="12"> <el-form-item prop="name" label="账户类型: "> <el-select v-model="edit.data.type" placeholder="请选择账户类型" style="width: 100%;"> <el-option v-for="(item,index) in dict.types" :key="index" :label="item.label" :value="item.value"> </el-option> </el-select> </el-form-item> </el-col> <el-col> <el-form-item prop="remark" label="备注: "> <el-input type="textarea" v-model="edit.data.remark" placeholder="请输入备注信息"></el-input> </el-form-item> </el-col> </el-form>

至此,问题成功解决

问题原理

带着问题,我们找一找源码,在el-form-item.vue的代码中发现了这样一个计算属性:

form() { let parent = this.$parent; let parentName = parent.$options.componentName; while (parentName !== 'ElForm') { if (parentName === 'ElFormItem') { this.isNested = true; } parent = parent.$parent; parentName = parent.$options.componentName; } return parent; },

这里通过当前组件,一级一级向上找,直到找到el-form组件就返回,而其他计算属性/方法依赖form计算属性,这也就能解释为什么remark表单项能正常点击,而name和type表单项无法点击的问题了。

总结

el-form下的el-form-item的dom级次务必一致,如有不一致的情况会导致表单项无法点击的问题

最新回复(0)