I have some question. I want debounce an emit event from child component to parent component ( using el-input in element plus).
I try learn some solutions but emit debounce not working such as watch input, emit modelValue. I want to pass 1 "debounce" parameter as above and prevent the code from working fine.
//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 = newValue)"
/>
</template>
//input
<script lang="ts" setup>
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'])
// const debounceInput = debounce(() => {
// let value = 'ok'
// emit('update:modelValue', value)
// }, props.debounce)
const debounceInput = (e: any) => {
let value = e.target.value
emit('update:modelValue', value)
}
</script>
<template>
<el-input
v-bind="$attrs"
:value="modelValue"
:placeholder="placeholder"
:type="type"
class="base-input"
:class="{
search: type === 'search'
}"
@input="debounceInput"
>
<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>
//debounce function
export const debounce = (callback: Function, delayTime: number) => {
let timeOut
return () => {
timeOut = setTimeout(() => callback(), delayTime)
}
}
debouncing a function:
export function debounce(func, timeout) {
let timeoutId;
return (...args) => {
clearTimeout(timeoutId);
timeoutId = setTimeout(() => {
func(...args);
}, timeout);
};
}
Then to use it:
<script>
import { debounce } from 'debounce.js'
const debouncedInput = debounce((e) =>
emit("update:modelValue", e.target.value),
300 // timeout in ms
);
</script>
with a generic <input>
for simplicity sake:
<template>
<input
:value="modelValue"
@input="debouncedInput"
placeholder="Please input"
type="text"
/>
</template>
Here is a codesandbox example. Should also work just fine when implemented with <el-input>
and typescript which I'll leave to you.
By the way, these properties you have on <CustomInput>
:
:modelValue="search"
@update:modelValue="(newValue: string) => (search = newValue)"
Can all be replaced with the following short-hand:
v-model="search"