欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 汽车 > 时评 > 从覆盖到拼接:优化 onInput 事件的输入

从覆盖到拼接:优化 onInput 事件的输入

2025/5/11 17:15:30 来源:https://blog.csdn.net/weixin_52648900/article/details/144066870  浏览:    关键词:从覆盖到拼接:优化 onInput 事件的输入

在使用 ElSelect 组件的 onInput 事件时,由于每次输入都触发搜索,导致请求频繁且新搜索结果覆盖了旧结果,无法实现输入数据的累积搜索。我们希望的是,每次搜索能够将新的输入内容与之前的内容拼接显示,从而实现用户的诉求。

ElSelect 组件

<ElSelectref={storeRef}filterableremoteremoteMethod={getSiteList}multipleclearablev-model={queryForm.value.pickUpSiteIdList}placeholder="请输入门店名称"onInput={(e) => { handleInput(e?.data || '', SelectEnum.store); }}>{siteList.value?.map((item) => (<ElOption label={item.siteName} value={item.siteId} />))}
</ElSelect>

onInput 事件

const handleInput = (query, type) => {if (type === SelectEnum.store) {storeRef.value.remoteMethod(query);}
};// 其余
const getSiteList = async (query = '') => {if (query) {const res = await querySiteList({siteName: query,});siteList.value = res.records;} else {siteList.value = [];}
};

目前现状展示,后面搜索的结果覆盖之前的搜索结果o(╥﹏╥)o。

可能第一反应就是,使用函数防抖,OK。

import { debounce } from 'lodash';const handleInput = debounce((query, type) => {if (type === SelectEnum.store) {storeRef.value.remoteMethod(query);}
}, 500);

展示为:

虽然效果好一些,但仍不是我们想要的结果,我希望搜索的是「上海南」,而不是「上海」「南」 。

可能会觉得,时间拉长点,会不会好一点,展示一下:

const handleInput = debounce((query, type) => {if (type === SelectEnum.store) {storeRef.value.remoteMethod(query);}
}, 2000);

显而易见,更加糟糕,因为间隔时间变长,对应的搜索也就更加精确,最后一次搜索就是「站」。

不妨换一个思路:

将之前的输入与当前输入拼接起来,每次用户输入时,等一小段时间再发起请求,这样可以减少请求次数并避免连续输入时产生多个请求。 

const searchContent = ref(''); // 当前输入框内容,拼接所有输入的内容
// 防抖定时器
let timeoutId = null;const handleInput = (query, type) => {// 处理输入拼接searchContent.value += query;// 清除之前的定时器,防止连续输入时发送多个请求if (timeoutId) {clearTimeout(timeoutId);}// 使用防抖,延迟搜索timeoutId = setTimeout(() => {if (type === SelectEnum.store) {storeRef.value.remoteMethod(searchContent.value);}}, 500); // 500ms 的防抖延迟
};

运行发现一个比较诧异的现象,输入内容包括那么多拼音,也不是我们想要的。 

再改进一下:

需要解决 累积拼接输入时产生的错误!!!这种问题通常是因为 onInput 事件触发时处理不当,导致历史内容和当前输入被错误拼接。

解决方法:以输入框当前值为准!

// 防抖定时器
let timeoutId = null;const handleInput = (query, type) => {// 清除之前的定时器,防止连续输入时发送多个请求if (timeoutId) {clearTimeout(timeoutId);}// 防抖延迟timeoutId = setTimeout(() => {nextTick(() => {if (type === SelectEnum.store) {const inputValue = storeRef.value?.$el.querySelector('input')?.value || '';storeRef.value.remoteMethod(inputValue);}});}, 500); // 防抖延迟 500ms
};

代码解释:

每次 onInput 事件触发时,直接使用 storeRef 引用直接获取输入框中当前的完整值,确保内容是正确的,而不是依赖传入的 onInput 参数或直接拼接,这避免了累积拼接错误。

使用 nextTick,确保在 DOM 更新后获取到最新的输入框值。

OK,到处实现完美解决!  

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词