需求描述
表单中,权限编号 是远程搜索组件 el-autocomplete ,该组件绑定值为 String 类型 提交时,业务需求需要传递权限编号 整个对象的值,包括 fetchId 和 fetchName 因此需要监听 el-autocomplete 的选择事件,拿到选择的对象,赋值给提交参数
初步逻辑
< el-form ref = " form" :model = " form" label-width = " 80px" :rules = " rules" class = " form" >
< el-form-item label = " 姓名" prop = " inputText" >
< el-input v-model = " form.inputText" placeholder = " 请输入内容" > </ el-input>
</ el-form-item>
< el-form-item label = " 居住地" prop = " selectVal" >
< el-select v-model = " form.selectVal" placeholder = " 请选择" >
< el-option
v-for = " item in options"
:key = " item.value"
:label = " item.label"
:value = " item"
value-key = " value"
>
</ el-option>
</ el-select>
</ el-form-item>
< el-form-item label = " 权限编号" prop = " fetchVal" >
< el-autocomplete
v-model = " form.fetchValFilter"
placeholder = " 请输入内容"
@select = " handleSelect"
:fetch-suggestions = " querySearchAsync"
value-key = " fetchName"
> </ el-autocomplete>
</ el-form-item>
< el-button type = " primary" @click = " onSubmit" > 提交</ el-button>
</ el-form>
querySearchAsync ( searchText, cb ) {
console. log ( "远程搜索输入内容" , searchText) ;
this . form. fetchVal = { } ;
setTimeout ( ( ) => {
let result = [ ] ;
for ( var i = 0 ; i < 10 ; i++ ) {
result. push ( {
fetchId : ( i + 1 ) * 1 ,
fetchName : "12345_" + ( i + 1 ) * 1 ,
} ) ;
}
console. log ( "远程搜索获取到的列表" , result) ;
cb ( result) ;
} , 300 ) ;
} ,
handleSelect ( item ) {
console. log ( "选择的对象" , item) ;
this . form. fetchVal = item;
} ,
rules 中,关于远程搜索的校验,应该是判断 this.form.fetchVal 对象中是否包含 fetchId 和 fetchName
rules : {
inputText : [ { required : true , message : "请填写内容" , trigger : "blur" } ] ,
selectVal : [
{
required : true ,
validator : ( rule, value, callback ) => {
if ( this . form. selectVal && this . form. selectVal. value) {
callback ( ) ;
} else {
callback ( new Error ( "请选择内容" ) ) ;
}
} ,
trigger : "change" ,
} ,
] ,
fetchVal : [
{
required : true ,
validator : ( rule, value, callback ) => {
console. log ( "change 事件被触发,开启校验" ) ;
console. log ( "校验的是对象" ) ;
if ( this . form. fetchVal && this . form. fetchVal. fetchId) {
callback ( ) ;
} else {
callback ( new Error ( "请选择内容" ) ) ;
}
} ,
trigger : "change" ,
} ,
] ,
} ,
问题出现
校验表单时,如果 el-autocomplete 的触发为 change ,则在输入的过程中,就会触发。此时还未执行 select 事件,this.form.fetchVal 为空对象,则会进入到校验抛错的判断中 校验表单时,如果 el-autocomplete 的触发为 blur ,在选中结果后,会先触发 blur 事件,后触发 select 事件,依旧拿不到 this.form.fetchVal ,会进入到校验抛错的判断中
fetchVal : [
{
required : true ,
validator : ( rule, value, callback ) => {
console. log ( "blur 事件被触发,开启校验" ) ;
console. log ( "this.form.fetchVal" , this . form. fetchVal) ;
if ( this . form. fetchVal && this . form. fetchVal. fetchId) {
callback ( ) ;
} else {
callback ( new Error ( "请选择内容" ) ) ;
}
} ,
trigger : "blur" ,
} ,
] ,
解决方式
方法一:延时操作
blur 会比 select 先触发,那么添加定时器,做一个延时,可以手动将判断放到 select 事件的后面
fetchVal : [
{
required : true ,
validator : ( rule, value, callback ) => {
console. log ( "blur 事件被触发" ) ;
console. log ( "this.form.fetchVal" , this . form. fetchVal) ;
setTimeout ( ( ) => {
console. log ( '此时才开启校验' ) ;
console. log ( "this.form.fetchVal" , this . form. fetchVal) ;
if ( this . form. fetchVal && this . form. fetchVal. fetchId) {
callback ( ) ;
} else {
callback ( new Error ( "请选择内容" ) ) ;
}
} , 200 ) ;
} ,
trigger : "blur" ,
} ,
] ,
方法二:手动控制触发校验的方式
移除 rules 中的校验,在提交校验之前,为当前项添加校验规则。或者在选中结果后为当前项添加校验规则,之后校验此项
handleSelect ( item ) {
this . form. fetchVal = item;
this . $refs. form. rules. fetchVal[ 0 ] . validator = ( rule, value, callback ) => {
if ( this . form. fetchVal && this . form. fetchVal. fetchId) {
callback ( ) ;
} else {
callback ( new Error ( "请选择内容" ) ) ;
}
} ;
this . $refs. form. validateField ( "fetchVal" , ( valid ) => {
if ( valid) {
console. log ( "对当前项进行校验-校验通过了" ) ;
}
} ) ;
} ,
onSubmit ( ) {
console. log ( "form" , this . form) ;
this . $refs. form. rules. fetchVal[ 0 ] . validator = ( rule, value, callback ) => {
if ( this . form. fetchVal && this . form. fetchVal. fetchId) {
callback ( ) ;
} else {
callback ( new Error ( "请选择内容" ) ) ;
}
} ;
this . $refs. form. validate ( ( valid ) => {
if ( valid) {
console. log ( "整个表单进行校验-校验通过了" ) ;
}
} ) ;
} ,
完整代码
export default {
data ( ) {
return {
form : {
inputText : "" ,
selectVal : { } ,
fetchVal : { } ,
fetchValFilter : "" ,
} ,
rules : {
inputText : [ { required : true , message : "请填写内容" , trigger : "blur" } ] ,
selectVal : [
{
required : true ,
validator : ( rule, value, callback ) => {
if ( this . form. selectVal && this . form. selectVal. value) {
callback ( ) ;
} else {
callback ( new Error ( "请选择内容" ) ) ;
}
} ,
trigger : "change" ,
} ,
] ,
fetchVal : [
{
required : true ,
validator : ( rule, value, callback ) => { } ,
trigger : "blur" ,
} ,
] ,
} ,
options : [
{ label : "北京" , value : 1 } ,
{ label : "天津" , value : 2 } ,
{ label : "上海" , value : 3 } ,
{ label : "重庆" , value : 4 } ,
] ,
} ;
} ,
mounted ( ) { } ,
methods : {
querySearchAsync ( searchText, cb ) {
console. log ( "远程搜索输入内容" , searchText) ;
this . form. fetchVal = { } ;
setTimeout ( ( ) => {
let result = [ ] ;
for ( var i = 0 ; i < 10 ; i++ ) {
result. push ( {
fetchId : ( i + 1 ) * 1 ,
fetchName : "12345_" + ( i + 1 ) * 1 ,
} ) ;
}
console. log ( "远程搜索获取到的列表" , result) ;
cb ( result) ;
} , 300 ) ;
} ,
handleSelect ( item ) {
this . form. fetchVal = item;
this . $refs. form. rules. fetchVal[ 0 ] . validator = ( rule, value, callback ) => {
if ( this . form. fetchVal && this . form. fetchVal. fetchId) {
callback ( ) ;
} else {
callback ( new Error ( "请选择内容" ) ) ;
}
} ;
this . $refs. form. validateField ( "fetchVal" ) ;
} ,
onSubmit ( ) {
console. log ( "form" , this . form) ;
this . $refs. form. rules. fetchVal[ 0 ] . validator = ( rule, value, callback ) => {
if ( this . form. fetchVal && this . form. fetchVal. fetchId) {
callback ( ) ;
} else {
callback ( new Error ( "请选择内容" ) ) ;
}
} ;
this . $refs. form. validate ( ( valid ) => {
if ( valid) {
console. log ( "整个表单进行校验-校验通过了" ) ;
}
} ) ;
} ,
} ,
} ;