element-ui下拉输入框+resetFields无法回显
文章目录
- 描述
- 原因
- 问题重现
- 解决方案
- 方法一
- 方法二
- 总结
描述
第一次进入页面,不做任何操作,点击重置按钮,再进行下拉选择,输入框并不能回显数据,点击搜索后,选中的数据就能显示出来。
重置代码,resetForm的底层用的是表单的resetFields。
resetFields的作用:对整个表单进行重置,将所有字段重置为初始值(而不是设置为空值)并移除校验结果
注意:一定要加上prop,否则无法清除
// 重置按钮操作
resetQuery: _.debounce(function () {
//重置表单
this.resetForm("queryForm");
//搜索
this.handleQuery();
}, 500),
原因
表单绑定的是搜索的对象内容,而表单的内容使用的是v-model来绑定,如果没给表单内容初始值,那么绑定的内容就不是响应式,打印出来也可以看见。所以就会出现搜索后才会回显选中的内容。
这时候就有两种解决方法
- 给表单初始值,让它变成响应式,但是如果表单内容有100个的话,得一个个加。
- 清空的时候,不必使用表单的清除属性resetField,而是使用封装好的清空对象方法。
问题重现
这里只给了请假类型初始值,而未给请假方式初始值。
<template>
<div style="margin-top: 100px">
<el-form
:model="form"
ref="ruleForm"
label-width="100px"
class="demo-ruleForm"
>
<el-form-item label="请假类型" prop="leaveType">
<el-select v-model="form.leaveType" placeholder="请选择请假类型">
<el-option label="事假" value="1"></el-option>
<el-option label="病假" value="2"></el-option>
</el-select>
</el-form-item>
<el-form-item label="请假方式" prop="leaveWay">
<el-select v-model="form.leaveWay" placeholder="请选择请假方式">
<el-option label="单次请假" value="1"></el-option>
<el-option label="长期请假" value="2"></el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="submitForm('ruleForm')"
>确定</el-button
>
<el-button @click="resetForm('ruleForm')">重置</el-button>
</el-form-item>
</el-form>
</div>
</template>
<script>
export default {
data() {
return {
form: {
leaveType: "",
},
};
},
methods: {
resetForm(formName) {
console.log("form", this.form);
this.$refs[formName].resetFields();
},
},
};
</script>
<style lang="scss" scoped></style>
解决方案
方法一
给表单初始值,让它变成响应式,可以很明显地看到表单的初始化内容,都有响应式。
form: {
leaveType: "",
leaveWay: "",
},
缺点是需要一个个加,很费时间。
方法二
不使用表单的resetFields清空表单,而是使用清空对象的cleanObject方法。
<template>
<div style="margin-top: 100px">
<el-form
:model="form"
ref="ruleForm"
label-width="100px"
class="demo-ruleForm"
>
<el-form-item label="请假类型" prop="leaveType">
<el-select v-model="form.leaveType" placeholder="请选择请假类型">
<el-option label="事假" value="1"></el-option>
<el-option label="病假" value="2"></el-option>
</el-select>
</el-form-item>
<el-form-item label="请假方式" prop="leaveWay">
<el-select v-model="form.leaveWay" placeholder="请选择请假方式">
<el-option label="单次请假" value="1"></el-option>
<el-option label="长期请假" value="2"></el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary">确定</el-button>
<el-button @click="resetForm(form)">重置</el-button>
</el-form-item>
</el-form>
</div>
</template>
<script>
export default {
data() {
return {
form: {},
};
},
methods: {
resetForm(formName) {
this.cleanObject(formName);
},
cleanObject(obj) {
// 判断对象是否为非对象或null
if (typeof obj !== "object" || obj === null) {
return obj;
}
// 判断对象是否为数组
if (Array.isArray(obj)) {
// 递归处理数组中的每个元素
return obj.map((item) => this.cleanObject(item));
}
// 如果是对象,则遍历其属性
for (const key in obj) {
// 判断值是否为数组
if (Array.isArray(obj[key])) {
// 如果是数组,则将其置为空数组
obj[key] = [];
} else {
// 递归处理对象中的每个值
obj[key] = this.cleanObject(obj[key]);
}
}
},
},
};
</script>
<style lang="scss" scoped></style>
总结
实际场景用方法二会比较好点,如果有100个下拉框,给初始值的话,那你就要给100个内容进行初始化,很浪费时间。在vue3中也存在这样的情况,不知道这是不是resetFields遗留下来的bug,还需要看一下resetFields的源码。具体的原理还需要大家在评论区进行补充,附上vue3试验的代码。
<template>
<el-form :model="form" ref="form" label-width="100px" class="demo-ruleForm">
<el-form-item label="请假类型" prop="leaveType">
<el-select v-model="form.leaveType" placeholder="请选择请假类型">
<el-option label="事假" value="1"></el-option>
<el-option label="病假" value="2"></el-option>
</el-select>
</el-form-item>
<el-form-item label="请假方式" prop="leaveWay">
<el-select v-model="form.leaveWay" placeholder="请选择请假方式">
<el-option label="单次请假" value="1"></el-option>
<el-option label="长期请假" value="2"></el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary">确定</el-button>
<el-button @click="resetForm(form)">重置</el-button>
</el-form-item>
</el-form>
</template>
<script setup>
import { ref } from "vue";
const form = ref({});
const resetForm = (formEl) => {
if (!formEl) return;
formEl.resetFields();
};
</script>