两次点击居然才触发 remote-method 事件?

在使用 Element Plus 的 <ElSelect> 组件时,可能会遇到这样一个尴尬场景:使用者第一次点击下拉框,未触发远程搜索;只有在第二次输入或再次点击时,才会真正调用 remote-method 并得到结果或提示

这种“点击两次才生效”的现象,会严重影响用户体验。下面简单讲述一下产生的原因和解决方法。

一、问题现象描述

如图所示,点击门店 Select 两次,第一次点击,remote-method 未被调用,没有任何提示。第二次点击,真正触发方法,开始发送请求,并弹出“该商户下无门店”的警告提示或展示结果。 

部分代码为:

<ElFormItem label="承接门店" prop="rentSiteId" placeholder='请选择门店'>
  <ElSelect
    v-model={form.value.rentSiteId}
    filterable
    clearable
    remote
    class="w-400"
    remote-method={filterStore}
    placeholder='请选择门店'
    disabled={disabled.value}
    onChange={changeSite}
    >
    {merchantStore.value?.map((kv) => (
      <ElOption key={kv?.siteId}
        label={kv?.siteName} value={kv?.siteId} />
    ))}
  </ElSelect>
</ElFormItem>
const filterStore = (cur: string) => {
  // xxx
  if (merchantStore.value?.length === 0 && form.value.rentMerchantId) {
    ElMessage({ type: 'warning', message: '当前商户下暂无门店' });
    return;
  }
  const currents = merchantStore.value?.filter((item: StoreItemType) => item.siteName.includes(cur));
  merchantStore.value = currents;
  // xxx
};
二、问题根本:remote-method 的触发机制

首先要明白 Element Plus 中 <ElSelect remote> 的设计原理:

  1. 懒加载思路
    remote 模式下,组件默认不在面板展开时马上发起请求,而是等待用户输入(输入框内容变化)后,才调用 remote-method(query: string)。这样做是为了减少不必要的网络请求,尤其是当选项集很大时,只在用户真的输入了关键字时才去过滤或搜索。

  2. 触发条件限制

    • 输入触发:当用户在下拉搜索框中敲入字符时,内部会检测到 input 事件,然后执行 remote-method,并传入当前搜索关键词 query(首次输入时 query 不为空;调用清空再输入空串时 query === '')。

    • 清空触发:若 clearable 且用户点击清空图标,此时输入框内容变为空串,也会走一次 remote-method('')。

    • 展开不触发:纯粹的面板打开(点击下拉图标或输入框)并不主动执行 remote-method,也就是说,如果用户既不输入新字符,也不点击清空图标,组件认为“用户不需要过滤”,就不会去调用远程方法。

以上触发机制,决定了第一次点击仅仅是“打开面板”,并没有任何输入内容变化或清空动作,所以 remote-method 不会执行。

总结一下:

  • 本质:remote-method 并非“面板展开即调用”,而是依赖于用户输入或清空操作。仅仅打开面板并不改变输入框内容,因此不会调用自定义方法。
  • 影响:用户在面板第一次打开时,看到空白列表且无提示,易产生误解,认为组件或接口出错。反复点击才触发提示,严重影响用户体验,甚至引发无谓的技术排查和沟通成本。
三、解决方案

利用 visible-change 主动触发一次过滤

最常用、也最轻量的做法是:当下拉面板展开时,主动调用一次 filterStore('') 或远程请求,从而绕过 remote-method 的懒触发。

<ElSelect
  v-model={form.value.rentSiteId}
  remote
  filterable
  clearable
  remote-method={filterStore}
  onVisibleChange={handleSiteVisibleChange}
  placeholder="请选择门店"
>
  {merchantStore.value.map(opt => (
    <ElOption key={opt.siteId} label={opt.siteName} value={opt.siteId} />
  ))}
</ElSelect>
const handleSiteVisibleChange = (visible: boolean) => {
  if (visible && form.value.rentMerchantId) {
    // 下拉框展开时触发一次过滤,模拟一次“清空输入”或“空字符串查询”
    filterStore('');
  }
};

这样,第一次展开面板时,就会立即执行 filterStore(''),进行提示或加载列表,告别“点两次”尴尬。

为什么可以解决呢?

  1. 主动触发与懒触发的区别:visible-change 无论输入内容有无变化,只要组件“打开”就会调用指定的方法,完全绕过了 remote-method 仅“输入后触发”的设计。
  2. 同步体验:用户一旦点击就能得到即时反馈,无需二次操作,大幅提升交互体验。
  3. 实现简单:只需多加一个回调,代码侵入性低,可以弥补组件设计上的空窗期。

最后总结一下 remote-method 触发机制

行为

会不会触发 remote-method

只点击下拉框(不输入)

不会

输入任意字符

清空输入框

会(传空字符串)

使用 visible-change 主动触发

会(自己调用 filter 方法)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值