You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue3+Nuxt3中Element Plus子组件emit事件防抖失效求助

Vue3+Nuxt3中Element Plus el-input子组件emit事件防抖失效的解决方法

问题核心原因

你的代码存在三个关键问题导致防抖失效:

  1. 防抖函数实现错误:原函数未清除旧定时器,每次输入都会新增独立定时器,无法实现"延迟执行最后一次操作"的防抖效果;同时未传递事件参数,回调无法获取输入值。
  2. 未正确绑定防抖逻辑:子组件中debounceInput直接触发emit,没有用防抖函数包裹处理。
  3. 响应式参数与ref更新错误:debounce props变化时防抖函数不会自动更新,且父组件中直接给ref变量赋值而非修改.value属性,导致响应式失效。

解决方案

步骤1:修复防抖函数

修改防抖函数,添加定时器清除逻辑并支持参数传递:

export const debounce = (callback: Function, delayTime: number) => {
  let timeoutId: NodeJS.Timeout | null = null;
  return (...args: any[]) => {
    // 清除上一次未执行的定时器
    if (timeoutId) clearTimeout(timeoutId);
    timeoutId = setTimeout(() => {
      callback(...args); // 传递调用时的参数
    }, delayTime);
  };
};

步骤2:子组件实现响应式防抖逻辑

使用computed根据debounce props动态生成防抖函数,确保延迟时间变化时自动更新:

<!-- input 子组件 -->
<script lang="ts" setup>
import { debounce } from '@/utils/debounce'; // 替换为你的防抖函数实际路径
import { computed } from 'vue';

interface Props {
  modelValue?: string;
  placeholder?: string;
  type: string;
  debounce: number;
}

const props = withDefaults(defineProps<Props>(), {
  modelValue: '',
  placeholder: 'Please input',
  type: 'text',
  debounce: 0
});

const emit = defineEmits(['update:modelValue']);

// 根据debounce参数动态生成防抖函数,debounce为0时直接执行
const debouncedEmit = computed(() => {
  if (props.debounce === 0) {
    return (value: string) => emit('update:modelValue', value);
  }
  return debounce((value: string) => {
    emit('update:modelValue', value);
  }, props.debounce);
});

const handleInput = (e: Event) => {
  const inputValue = (e.target as HTMLInputElement).value;
  debouncedEmit.value(inputValue);
};
</script>

<template>
  <el-input
    v-bind="$attrs"
    :model-value="modelValue"
    :placeholder="placeholder"
    :type="type"
    class="base-input"
    :class="{ search: type === 'search' }"
    @input="handleInput"
  >
    <template #suffix>
      <el-icon>
        <img
          v-if="type === 'search'"
          class="w-[18px] h-[18px] mx-auto cursor-pointer"
          src="images/search.svg"
          alt="logo"
        />
      </el-icon>
    </template>
  </el-input>
</template>

步骤3:修复父组件的ref更新逻辑

父组件中search是ref对象,必须通过.value属性更新值:

<!-- Custom Input 父组件 -->
<script lang="ts" setup>
const search = ref('');
</script>

<template>
  <CustomInput
    :model-value="search"
    placeholder="Search"
    type="search"
    class="w-full md:max-w-[330px]"
    :debounce="500"
    @update:modelValue="(newValue: string) => (search.value = newValue)"
  />
</template>

内容的提问来源于stack exchange,提问作者M12H

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 15:47:29