问题描述
我做了如下图的界面,技术栈是Vue2+ElementUI,主要需要实现的功能是:资源的配置(其实看图就知道了,没什么好说的哈哈)。本身也不是个很难的需求,但是,测试提出,当多次点击+,-号的时候,会出现点击了,但是数字不变化的情况(有时偶发有时频率很高)。当时觉得很纳闷,去官网试了一下,官网的也是这样!然后再试了一下,Vue2对应的Element存在这个问题,Vue3的没有。
解决方法
总体思路:禁用InputNumber组件的点击逻辑,自己来实现。
代码(以CPU那一行为例)
<el-form-item
label="CPU"
size="small"
style="margin-bottom: 15px"
prop="cpu"
>
<el-popover trigger="hover" placement="top">
<p class="info_p">
由于Notebook为单机实例,因此剩余可分配核数为当前项目剩余可用配额和集群内最大单机空闲核数的最小值。
</p>
<i
class="el-icon-warning-outline"
slot="reference"
style="margin-left: -10px;"
></i>
</el-popover>
<div class="input-number" @click="changeClickHandler($event, 'cpu')">
<el-input-number
size="small"
:value="form.cpu"
@blur="changeHandler($event, 'cpu')"
:min="0"
:precision="0"
:max="availableTrain.cpu"
style="width: 220px"
:placeholder="`剩余可分配: ${availableTrain.cpu}`"
></el-input-number
> 核
</div>
<p
v-if="!isNaN(availableTrain.cpu)"
style="color: gray;height: fit-content;padding-left: 50px;margin-bottom: -5px;"
>
剩余可分配: {{ availableTrain.cpu - form.cpu || 0 }} 核
</p>
</el-form-item>
methods: {
changeHandler(e, type) {
this.form[type] = parseInt(e.target.value);
},
changeClickHandler(e, type) {
if (
["el-icon-minus", "el-input-number__decrease"].includes(
e.target.classList[0]
)
) {
this.form[type] - 1 >= 0 && (this.form[type] = this.form[[type]] - 1);
} else if (
["el-icon-plus", "el-input-number__increase"].includes(
e.target.classList[0]
)
) {
this.form[type] + 1 <= this.availableTrain[type] &&
(this.form[type] = this.form[type] + 1);
}
},
}
变化点:
- 使用:value代替v-model。v-model是由v-bind:value(即:value)和v-on:input(即@input)结合起来的语法糖,作用是实现数据的双向绑定。:value将 初始化时 data的数据绑定到input上,当input里面的值变化时,通过触发@input事件修改data的值,实现数据双向绑定。去掉v-model改用:value,使得只有在初始化的时候才将data上面的数据绑定到input上,之后的逻辑需要自行实现。
- 由于el-input-numnber组件上面没法直接绑定click事件,利用事件冒泡,在他外面包一个div并绑定click事件changeClickHandler,当点击的时候判断点击元素的类名来得知点击的是+号还是-号,进而更新input框内的值。
- 当用户在input框里直接输入值时,当失焦后,触发changeHandler,更新表单里的值。PS: 输入值后,e.target.value 为string类型的。当时遇到的bug就是,当我输入数据失焦之后,点击➕没有反应,点击-之后有反应;点击-之后可以点击+,点击+之后点击-,又可以点击+…觉得这个bug绕不看也可以哈哈哈,很诡异。但解决方法就是parseInt将string转换为数字类型的。
总结
Vue2官方已经不更新了,但是项目比较老,技术栈就是vue2,没办法了。实际上上面这个bug更新到vue3对应的elementui就能解决,但是如果项目用的技术栈比较老,没法更新的话,那就可以参考一下我的方法。