这是不久前在项目中发现了这个诡异的用法&问题🙃, 后尝试重新搭建一个环境梳理一遍. 项目已上传到codesandbox.
- 因笔者能力不足,探究后未能找到一种完美的解决办法,希望后续有大佬能够指点迷津,感激不尽。如读者有类似问题请尝试多种解决办法后综合考虑。
问题的具体表现如图所示或查看codesandbox在线环境. 这是从正常运行的项目中精简后的问题场景。
因分析篇幅较长,为节省时间,可直接尝试下方的解决方式。
分析
-
这是笔者第一次见到这种用法很新奇。el-table嵌套着父子两个el-table-column,子级el-table-column使用了自定义插槽,并在头部嵌入el-input。
-
当尝试将此用法精简出来梳理时,笔者发现el-table-column的selection、timeFlag和resultArr的组合用法缺一不可。更改其中之一都会使input无法输入
-
搜索网上的资料,得到“嵌套层次太深,vue双向绑定失效”这么一个结论。之后以el-input组件为突破点进行源码调试(关于调试方法可以见之前写的一篇文章:juejin.cn/post/706778…)
-
找到Input源码的setNativeInputValue方法,填入log。
注意⚠️:笔者这里使用的源码路径是
/node_modules/element-ui/lib/input.js
如果单纯分析源码还是查看input.vue组件源码较为清晰。
setNativeInputValue: function setNativeInputValue() { var input = this.getInput(); if (!input) return; if (input.value === this.nativeInputValue) return; console.log('Run setNativeInputValue ', ' 当前value:', this.value, '当前input Value:', input.value); input.value = this.nativeInputValue; },
这里分别输入了
1
2
;可以看到运行了两遍setNativeInputValue方法,第一遍props的value值正常,第二遍显示未定义 -
为什么会运行两遍?先搜索哪里用到了这个方法。找到两个关键点。
-
在782行watch监听
nativeInputValue
改变的方法中填入lognativeInputValue: function nativeInputValue() { console.log('监听nativeInputValue更新', this.value); this.setNativeInputValue(); },
在871行
handleInput
方法改造一下并填入loghandleInput: function handleInput(event) { // should not emit input during composition // see: https://github.com/ElemeFE/element/issues/10516 if (this.isComposing) return; // hack for https://github.com/ElemeFE/element/issues/8548 // should remove the following line when we don't support IE if (event.target.value === this.nativeInputValue) return; this.$emit('input', event.target.value); // ensure native input value is controlled // see: https://github.com/ElemeFE/element/issues/12850 this.$nextTick(() => { console.log('Run handleInput') this.setNativeInputValue() }); },
观察运行结果,如图所示
-
产生这种结果的影响又是什么?没想通。undefined既然出在handleinput方法那先把
this.setNativeInputValue()
注释掉再试试。 -
结果如图所示
可以看到三个输入框的输入结果并不一致。和codesandbox所演示的不相同。输入问题虽然已经正常,但是使用这种解决方式并不可取。
-
后续因为时间关系无法进行,探究就暂时告一段落。
“解决”办法
1. 使用原生input代替el-input组件
使用原生的input组件代替el-input组件是笔者认为最为保险也是笔者使用的解决办法。
样式上直接仿照el-input写即可。
方法上就需要看迁移成本了
2. 怪异使用
这种怪异的使用方式并不推荐
参照链接:codesandbox.io/s/wen-ti-ce…
3. $forceUpdate
可以尝试在el-input的input方法中调用this.$forceUpdate()
因对笔者应用场景无效,只是作为一个参考。
4. 修改源码
可按照本文的分析思路
参照第7条,注释掉源码中884行this.setNativeInputValue()
方法
可临时解决 但此方式带来的影响未知 极不推荐