refactor: extract useDebounce composable from 4 duplicate copies

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-05-12 21:19:30 +08:00
parent beaf7c6203
commit 2a2b4c639e
5 changed files with 13 additions and 42 deletions
@@ -0,0 +1,9 @@
export function useDebounce<T extends (...args: any[]) => any>(fn: T, delay: number) {
let timer: ReturnType<typeof setTimeout> | null = null
const debounced = (...args: Parameters<T>) => {
if (timer) clearTimeout(timer)
timer = setTimeout(() => fn(...args), delay)
}
const cancel = () => { if (timer) clearTimeout(timer) }
return { debounced, cancel }
}
+1 -11
View File
@@ -185,17 +185,7 @@ import { ref, reactive, computed, onMounted, onUnmounted } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { Search, Refresh, Plus, Connection, Right, Setting } from '@element-plus/icons-vue'
import api from '../api'
// Debounce helper
function useDebounce<T extends (...args: any[]) => any>(fn: T, delay: number) {
let timer: ReturnType<typeof setTimeout> | null = null
const debounced = (...args: Parameters<T>) => {
if (timer) clearTimeout(timer)
timer = setTimeout(() => fn(...args), delay)
}
const cancel = () => { if (timer) clearTimeout(timer) }
return { debounced, cancel }
}
import { useDebounce } from '../composables/useDebounce'
const loading = ref(false)
const search = ref('')
+1 -10
View File
@@ -103,16 +103,7 @@ import { ref, reactive, onMounted, onUnmounted } from 'vue'
import { ElMessage } from 'element-plus'
import { Notebook, Warning, Timer, Search, Refresh } from '@element-plus/icons-vue'
import api from '../api'
function useDebounce<T extends (...args: any[]) => any>(fn: T, delay: number) {
let timer: ReturnType<typeof setTimeout> | null = null
const debounced = (...args: Parameters<T>) => {
if (timer) clearTimeout(timer)
timer = setTimeout(() => fn(...args), delay)
}
const cancel = () => { if (timer) clearTimeout(timer) }
return { debounced, cancel }
}
import { useDebounce } from '../composables/useDebounce'
const loading = ref(false)
const searchPath = ref('')
+1 -11
View File
@@ -161,17 +161,7 @@ import { ref, reactive, computed, onMounted, onUnmounted } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { Search, Refresh, Memo, CircleCheck, Warning } from '@element-plus/icons-vue'
import api from '../api'
// Debounce utility
function useDebounce<T extends (...args: any[]) => any>(fn: T, delay: number) {
let timer: ReturnType<typeof setTimeout> | null = null
const debounced = (...args: Parameters<T>) => {
if (timer) clearTimeout(timer)
timer = setTimeout(() => fn(...args), delay)
}
const cancel = () => { if (timer) clearTimeout(timer) }
return { debounced, cancel }
}
import { useDebounce } from '../composables/useDebounce'
const loading = ref(false)
const search = ref('')
+1 -10
View File
@@ -140,16 +140,7 @@ import { ref, reactive, onMounted, onUnmounted } from 'vue'
import { ElMessage } from 'element-plus'
import { Timer, CircleCheck, CircleClose, Loading, Search, Refresh } from '@element-plus/icons-vue'
import api from '../api'
function useDebounce<T extends (...args: any[]) => any>(fn: T, delay: number) {
let timer: ReturnType<typeof setTimeout> | null = null
const debounced = (...args: Parameters<T>) => {
if (timer) clearTimeout(timer)
timer = setTimeout(() => fn(...args), delay)
}
const cancel = () => { if (timer) clearTimeout(timer) }
return { debounced, cancel }
}
import { useDebounce } from '../composables/useDebounce'
const loading = ref(false)
const search = ref('')