elementUI中el-autocomplete和el-select用法和各种坑

最近在vue2+elementUI的项目中遇到了很多坑,这里记录一下,并附上我避坑的解决方案,希望对大家今后的开发有所帮助。

需求:要在文本框中通过输入关键字模糊搜索出一个列表,在列表中选中一个值后,这个选中的对象的其他属性要赋值到提交对象上,用于提交。


我最开始考虑到用el-autocomplete远程搜索自动补全组件,用法是这样的:

<el-autocomplete
	v-model="aduitObj.tmpCompanyName"
	:fetch-suggestions="queryCompanyAsync"
	placeholder="模糊搜索公司名称"
	@select="handleSelectCompany"
	:trigger-on-focus="false"
	:debounce=0
	clearable
>
	<i slot="suffix" class="el-input__icon el-icon-search"></i>
</el-autocomplete>



async queryCompanyAsync(queryString, cb){//模糊搜索公司名称
    console.info("query------",queryString, "tmpCompanyName====",this.aduitObj.tmpCompanyName);
    if(!this.aduitObj.applyType){
        this.$alert('请先选择公司类型!', '警告', { confirmButtonText: '确定' });
        return;
    }else if(!queryString || queryString.length==0 || queryString.trim().length==0){
        cb([]);
        return;
    }
    let param = {
        name: queryString,
        type: this.aduitObj.applyType
    };
    let {data: res} = await queryCompanysByName(JSON.stringify(param));
    if(res && res.success){
        var resArr = res.result.map(function(rItem){
            rItem.value = rItem.company;
            return rItem;
        });
        cb(resArr);
    }
},
handleSelectCompany(val){//选择某个公司
    console.info("select company=======",val);
    this.aduitObj.tmpCompanyName = val.company;
    this.aduitObj.authCompanyId = val.id;//回显和判断那里用的是这个id
	//buthCompanyName/buthCompanyId/buthCompanyXId都是提交接口需要的参数
    this.aduitObj.buthCompanyName = val.company;
    this.aduitObj.buthCompanyId = val.id;
    this.aduitObj.buthCompanyXId = val.xId;
},

这里有个坑,fetch-suggestions接收函数需要执行cb()回调函数并把数组返回到cb的回调参数中。还有一点,需要格外注意,数组中每个值必须得有value字段,最终选中的value值会自动赋值给v-model的值。

继续完善,需要给el-autocomplete加个必填项校验,需要这样做:
(这里一并讲一下elemenutui双属性的校验写法el-form-item 的props写2个属性,逗号分隔开,校验规则跟这2个属性名对应即可。)

<el-form :model="aduitObj" :rules="aduitRules" ref="aduitRules" label-width="150px">
	<el-form-item label="认证公司选择:" prop="applyType,tmpCompanyName" v-show="aduitObj.status==1" style="margin-bottom: 22px;">
		<el-row :gutter="0">
			<el-col :span="4">
				<el-form-item prop='applyType'>
					<el-select v-model="aduitObj.applyType" placeholder="请选择" @change="changeApplyType">
						<el-option label="客户" value="1"></el-option>
						<el-option label="经销商" value="2"></el-option>
					</el-select>
				</el-form-item>
			</el-col>
			<el-col :span="20">
				<el-form-item prop='tmpCompanyName'>
					<el-autocomplete
						......  ......
					</el-autocomplete>
				</el-form-item>
			</el-col>
		</el-row>
	</el-form-item>
	。。。。。。
</el-form>



export default {
    components: {  },
    data(){
		var checkApplyType = (rule, value, callback) => {
            if (this.aduitObj.status==1 && !value) {
                return callback(new Error('请选择认证公司类型!'));
            }
            return callback();
        };
		var checkCompanyId = (rule, value, callback) => {
            console.info("checkCompanyId-------", value, this.aduitObj.status,this.aduitObj.authenticationCompanyId)
            if (this.aduitObj.status==1 && (!value || !this.aduitObj.authCompanyId)) {//编辑回显值的时候用的是authCompanyId值
                return callback(new Error('请选择认证公司!'));
            }
            return callback();
        };
		return {
            aduitObj:{},
			... ...
			aduitRules:{
				...... ......
				applyType:[{ validator: checkApplyType, trigger: 'change' }],
				tmpCompanyName:[{ validator: checkCompanyId, trigger: 'change' }],
			},				
		}
	}
}

由于业务需要在切换公司类型的时候清空autocomplete公司名称 ,我是这样做的:

changeApplyType(){
	console.info("into-----changeApplyType---")
	//切换公司类型,清空上次输入的公司名称
	const kongObj = {
		id: "",
		erpId: "",
		company: ""
	};
	this.handleSelectCompany(kongObj);
},

这里有个坑:手动执行handleSelectCompany方法去清空值,容易出现问题:当切换公司类型后,能成功清空公司名称。但出现了问题 ,在输入关键字模糊搜索后,关键字在文本框中不显示,并且选中列表中某项后也在文本框中不显示。

解决办法是:changeApplyType方法中,this.aduitObj.tmpCompanyName = "";这样清空文本框的值。
但是其他id值没被清空,还是上一次选择的,在提交的时候随便输入一个名字,没选择,对应的id是有值的,还能提交,这就是另外一个bug了。

又或者是如果第一次搜索”北京“,出来北京的列表,选择”北京美丽安全有限公司“后,再次把”美丽安全有限公司“删掉,在弹出的列表中没选择,直接点击旁边,隐藏了列表,再点击提交按钮。仍然能提交成功,且保存的名字和id是北京美丽安全有限公司的,跟文本框显示出来的北京又不符合了。
于是打算在规则必填项校验checkCompanyId方法里面加个:
else if(this.aduitObj.status==1 && !!value && !!this.aduitObj.authCompanyId && value!=this.aduitObj.authCompanyName){
    return callback(new Error('请重新搜索并选择认证公司!'));
}

这样加上后,提交的时候,校验tmpCompanyName 名称和上次选中的authCompanyName名称不一致就提示,貌似解决了这个问题。

但又出现新的问题,打开dialog中首次输入公司,查询出来的列表。当关闭dialog后,再次打开别的记录dialog后,什么也没输入,点击上去,就直接展示出上次历史查询出来的列表。

想要清空掉历史记录,只能手动调用fetch-suggestions接收函数的方法,让其在关闭dialog或打开dialog的时候清空历史列表。可是这个方法接收2个参数,第一个是查询的字符串,第二个是callback函数。这个callback函数不知道传递啥才能 自动调用autocomplete组件

到此为止,陷入深深的迷茫中。

在别的同事的帮助下,选择el-select远程搜索组件解决问题。
使用方法是:

<el-select
	v-model="aduitObj.tmpCompanyObj"
	value-key="id"
	filterable
	remote
	placeholder="模糊搜索公司名称"
	:remote-method="queryCompanyAsync"
	@change="toSelectCompany"
	:loading="mhLoading" style="width:90%">
	<el-option
		v-for="item in mhCompanyList"
		:key="item.id"
		:label="item.company"
		:value="item">
	</el-option>
</el-select>

请注意因为select选择选中一般是值,我这里需要的是选中对象。因为要给其他属性赋值。

这里有个坑: 最开始我没有加value-key,出现了问题“当模糊搜索选中某值的时候,所有的值都会被自动选中,显示蓝色,并且文本框中默认显示最后一个被选中的值”。解决办法是加value-key,我最开始以为加在el-option上。试验后不行,最终发现是要加在el-select上。

这里需要List列表,也就是queryCompanyAsync远程查询到的列表直接赋值给option的list即可。

el-select也会出现跟el-complete一样,记录上一次搜索的历史记录的问题。只需要在切换公司的时候,清空列表即可。

changeApplyType(){
	console.info("into-----changeApplyType---")
	//切换公司类型,清空上次输入的公司名称
	const kongObj = {
		id: "",
		erpId: "",
		company: ""
	};
	// this.handleSelectCompany(kongObj);
	// this.aduitObj.tmpCompanyName = "";
	this.$set(this.aduitObj, "tmpCompanyObj", kongObj);
	this.mhCompanyList = [];
},

这里有个坑,直接设置tmpCompanyObj为一个空对象,是不生效的。this.aduitObj.tmpCompanyObj = {
        id: "",
        erpId: "",
        company: ""
};

要使用this.$set的方式才生效。

要使用:this.$set(this.aduitObj, "tmpCompanyObj", kongObj);

还有一个巨坑的地方:

在打开编辑dialog回显值的时候,对于非文本框/非select标准下拉等组件,对对象的某属性直接赋值都无效。需要使用  this.$set的方式。

<el-form-item label="审核意见:">
	<el-input type="textarea" v-model="aduitObj.reviewOpinions"></el-input>
</el-form-item>



//审核意见 回显值
let yijian = this.aduitObj.reviewOpinions ||  this.aduitObj.reviewComments;
this.$set(this.aduitObj, "reviewOpinions", yijian);

========================================


<el-form-item prop='applyType'>
	<el-select v-model="aduitObj.applyType" placeholder="请选择" @change="changeApplyType">
		<el-option label="客户" value="1"></el-option>
		<el-option label="经销商" value="2"></el-option>
	</el-select>
</el-form-item>

this.aduitObj.applyType = this.aduitObj.applyType ? this.aduitObj.applyType+"" : "";

在取消dialog中:

resetAduitForm(formName){//取消 审核

            this.$refs[formName].resetFields();//重置验证消息

            this.mhCompanyList = [];//模糊搜索公司名称结果集

            this.aduitDialog = false;//审核对话框隐藏

},

这是我开发中遇到的问题的回忆录。
如大侠们有更好的解决方案,还请大侠们多多提点,欢迎发表不同观点,多多留言。

  • 18
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值