这是我参与2022首次更文挑战的第2天,活动详情查看:2022首次更文挑战
问题
最近在写一个管理平台,使用vue + elementUI,有个表单需求,里面有个表单项需要动态切换。
比如一个单选框,如果选了选项1,则下面展示表单项1,如果选了选项2,则下面展示表单项2。
代码如下:
<el-form :model="form" :rules="formRule" ref="form">
<el-form-item prop="status">
<el-radio v-model="form.status" :label="true">key1</el-radio>
<el-radio v-model="form.status" :label="false">key2</el-radio>
</el-form-item>
<div v-if="form.status">
<el-form-item prop="key1" label="key1:">
<el-input v-model="form.key1"></el-input>
</el-form-item>
</div>
<div v-else>
<el-form-item prop="key2" label="key2:">
<el-input v-model="form.key2"></el-input>
</el-form-item>
</div>
<el-button @click="reset">重置</el-button>
</el-form>
export default {
name: 'HelloWorld',
data () {
return {
form: {
key1: 'val1',
key2: 'val2',
status: true
},
formRule: {
key1: [{
required: true, trigger: 'blur', message: '请填写'
}],
key2: [{
required: true, trigger: 'blur', message: '请填写'
}]
}
}
},
methods: {
reset () {
this.$refs.form.resetFields()
}
}
}
效果如下:
- 当你选择key1的时候,下面展示的是key1,input的value是val1
- 当你选择key2的时候,下面展示的是key2,input的value是val2
正常是没有问题。
但是如果这是需要我清空表单的时候,调用了this.$refs.form.resetFields()的方法。
可以看当我点重置后,key2的value变成了val1。 直接重置成key1的value值了,这是有问题的。
分析
为什么会出现这样的问题呢? 难道是跟v-if有关?
苦思无果,只能去看看el-form的代码了。
el-form的resetFields方法会调用el-form-item的resetField方法。
el-form-item会在mounted钩子函数的时候记录initialValue(初始值)
然后重置的时候会使用这个初始值去重置。
正常看下来这流程没有问题啊。
但是你仔细想一想,虽然我们用了v-if来切换,但是我们用到都是同一个组件,el-form-item。
对于相同的组件或者元素,如果key没有设置的时候,vue是会进行复用的。
vue会做缓存,即使你使用了v-if,但是对于相同的组件,切换的时候组件的created,mounted等钩子函数只会触发第一次,之后就不会触发。
然后el-form-item是在mounted钩子函数里面记录初始值,所以就导致记录不到第二个表单项的初始值。
解决
那该怎么处理?
vue的key属性,这时候就可以派上用场了。
所以我们可以给组件设置各自的key,让它们在v-if切换的时候,触发组件的生命周期钩子。
<div v-if="form.status">
<el-form-item prop="key1" label="key1:" key="key1">
<el-input v-model="form.key1"></el-input>
</el-form-item>
</div>
<div v-else>
<el-form-item prop="key2" label="key2:" key="key2">
<el-input v-model="form.key2"></el-input>
</el-form-item>
</div>
可以看到点了重置之后是正常的了。
大家如果有其它方法也可以在评论区交流讨论。