前言
这个功能看似很简单,就是下拉选选完后调用接口,完成后将接口返回的数据回显到其他的输入框中。如果是按照vue3默认的写法一会就写完了,但是对于vue-element-admin-plus来说事情没有这么简单。
我这里要完成一个功能,选择邮件接收人后要将ta的邮箱地址回显到输入框中,这样就不需要我再去找ta的邮箱地址了。
踩坑过程
由于vue-element-admin-plus使用schema列表去给页面显示的,我第一个想到的就是给schema数组中的“邮件接收人邮箱”的value手动赋值,就像这样:
// 以下代码均在const schema = reactive<FormSchema[]>([])的数组中
{
field: 'toAccountId',
label: '邮件接收人',
component: 'Select',
componentProps: {
placeholder: '请选择邮件接收人',
clearable: true,
filterable: true,
options: accountList,
onChange: async (value) => {
console.log('value', value)
const res = await accountFindForMailApi(value)
schema.filter((item) => item.field === 'toEmail')[0].value = res.d.email
}
}
}
这种写法简单粗暴,但是这只能在第一次选择后生效,之后再次选择就完全没有效果了,这么写肯定是有问题的。
之后我将目光转到Form中的formRef对象
<Form :rules="rules" @register="formRegister" :schema="schema" ref="formRef" />
在查看了封装完的Form源码后,得知formModel就是表单对象,里面包含了整个表单的数据
那我就改它吧,写法改成了这样:
{
field: 'toAccountId',
label: '邮件接收人',
component: 'Select',
componentProps: {
placeholder: '请选择邮件接收人',
clearable: true,
filterable: true,
options: accountList,
onChange: async (value) => {
console.log('value', value)
const res = await accountFindForMailApi(value)
formRef?.value?.formModel?.toEmail = res.d.email
}
}
}
然后不出意外的出意外了,代码报错了:
说明这条路也有问题,然后我又进行了大量尝试和摸索,后面各种乱七八糟的尝试我就不放了,避免无关篇幅过长
最终解决
换一种写法就好了:
{
field: 'toAccountId',
label: '邮件接收人',
component: 'Select',
componentProps: {
placeholder: '请选择邮件接收人',
clearable: true,
filterable: true,
options: accountList,
onChange: async (value) => {
console.log('value', value)
const res = await accountFindForMailApi(value)
// formRef?.value?.formModel?.toEmail = res.d.email
const formModel = formRef?.value?.formModel
formModel.toEmail = res.d.email
}
}
}
如代码所示,将formRef?.value?.formModel?.toEmail中间拆出一个常量就好了,问题就解决了。对我这么一个长期写惯java的人来说简直是匪夷所思,这不是等价的吗,为什么一个就报错,一个就完美解决了问题。我问了一下做前端的同事,他也觉得不可思议,说可能是TypeScript的解释器可能出现了问题。我也希望能有大佬跟我解释一下其中的缘由,非常感谢!