feat(邀请BDLeader、BD、代理): 搜索对接防抖功能,并为防抖功能新增第一次立即执行功能

This commit is contained in:
hzj 2025-11-28 17:50:14 +08:00
parent 9575165640
commit b93d12680d
4 changed files with 115 additions and 67 deletions

View File

@ -1,43 +1,57 @@
import { getCurrentInstance, onUnmounted } from 'vue'; import { getCurrentInstance, onUnmounted } from 'vue'
// 防抖 // 防抖
export function useDebounce(fn, delay = 500) { export function useDebounce(fn, delay = 500, immediate = false) {
let timer = null; let timer = null
let instance = getCurrentInstance(); // 获取当前组件实例 let instance = getCurrentInstance() // 获取当前组件实例
const debounced = (...args) => { const debounced = (...args) => {
if (timer) clearTimeout(timer); if (timer) clearTimeout(timer)
if (immediate && !timer) {
// 立即执行
fn.apply(this, args)
}
timer = setTimeout(() => { timer = setTimeout(() => {
fn(...args); if (!immediate) fn.apply(this, args)
}, delay); timer = null // 清理timer引用
}; }, delay)
}
// 取消防抖执行
debounced.cancel = () => {
clearTimeout(timer)
timer = null
}
// 立即执行
debounced.flush = (...args) => {
clearTimeout(timer)
timer = null
fn.apply(this, args)
}
if (instance) { if (instance) {
// 自动注册卸载钩子(仅组件内生效) // 自动注册卸载钩子(仅组件内生效)
onUnmounted(() => { onUnmounted(() => {
clearTimeout(timer); // 清理定时器 debounced.cancel()
timer = null; })
});
} else {
// 非组件环境返回手动清理方法
debounced.cancel = () => {
clearTimeout(timer);
timer = null;
};
} }
return debounced; return debounced
} }
// 节流 // 节流
export function useThrottle(fn, delay = 1000) { export function useThrottle(fn, delay = 1000) {
let lastCall = 0; let lastCall = 0
const throttled = (...args) => { const throttled = (...args) => {
const now = Date.now(); const now = Date.now()
if (now - lastCall < delay) return; if (now - lastCall < delay) return
lastCall = now; lastCall = now
fn(...args); fn(...args)
}; }
return throttled; return throttled
} }

View File

@ -218,9 +218,12 @@
</template> </template>
<script setup> <script setup>
import { computed, onMounted, ref } from 'vue'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import GeneralHeader from '@/components/GeneralHeader.vue' import { setDocumentDirection } from '@/locales/i18n'
import { showError, showSuccess } from '@/utils/toast.js' import { showError, showSuccess } from '@/utils/toast.js'
import { useDebounce } from '@/utils/useDebounce'
import { searchUser } from '@/api/userInfo' import { searchUser } from '@/api/userInfo'
import { import {
invitedList, invitedList,
@ -229,8 +232,8 @@ import {
handleInvite, handleInvite,
cancelInvite, cancelInvite,
} from '@/api/bdCenter.js' } from '@/api/bdCenter.js'
import { computed, onMounted, ref } from 'vue'
import { setDocumentDirection } from '@/locales/i18n' import GeneralHeader from '@/components/GeneralHeader.vue'
const { t, locale } = useI18n() const { t, locale } = useI18n()
@ -278,19 +281,28 @@ const handleInputChange = () => {
} }
} }
// //
const handleEnterPress = async () => { const debouncedSearch = useDebounce(
console.log('搜索用户id', searchQuery.value) async () => {
searchResults.value = [] console.log('搜索用户id', searchQuery.value)
selectedUser.value = {} searchResults.value = []
disInvite.value = true selectedUser.value = {}
if (searchQuery.value.trim()) { disInvite.value = true
const resSearchUser = await searchUser(searchQuery.value) if (searchQuery.value.trim()) {
if (resSearchUser.status && resSearchUser.body) { const resSearchUser = await searchUser(searchQuery.value)
let targetUserInfo = { userProfile: resSearchUser.body } if (resSearchUser.status && resSearchUser.body) {
searchResults.value.push(targetUserInfo) let targetUserInfo = { userProfile: resSearchUser.body }
searchResults.value.push(targetUserInfo)
}
} }
} },
500,
true
)
//
const handleEnterPress = async () => {
debouncedSearch()
} }
// //

View File

@ -217,17 +217,20 @@
</template> </template>
<script setup> <script setup>
import { computed, onMounted, ref } from 'vue'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import GeneralHeader from '@/components/GeneralHeader.vue' import { setDocumentDirection } from '@/locales/i18n'
import { showError, showSuccess } from '@/utils/toast.js' import { showError, showSuccess } from '@/utils/toast.js'
import { useDebounce } from '@/utils/useDebounce'
import { searchUser } from '@/api/userInfo' import { searchUser } from '@/api/userInfo'
import { import {
invitedList, // invitedList, //
inviteToBeBD, // inviteToBeBD, //
cancelInvite, // () cancelInvite, // ()
} from '@/api/bdLeaderCenter.js' } from '@/api/bdLeaderCenter.js'
import { computed, onMounted, ref } from 'vue'
import { setDocumentDirection } from '@/locales/i18n' import GeneralHeader from '@/components/GeneralHeader.vue'
const { t, locale } = useI18n() const { t, locale } = useI18n()
@ -275,19 +278,28 @@ const handleInputChange = () => {
} }
} }
// //
const handleEnterPress = async () => { const debouncedSearch = useDebounce(
console.log('搜索用户id', searchQuery.value) async () => {
searchResults.value = [] console.log('搜索用户id', searchQuery.value)
selectedUser.value = {} searchResults.value = []
disInvite.value = true selectedUser.value = {}
if (searchQuery.value.trim()) { disInvite.value = true
const resSearchUser = await searchUser(searchQuery.value) if (searchQuery.value.trim()) {
if (resSearchUser.status && resSearchUser.body) { const resSearchUser = await searchUser(searchQuery.value)
let targetUserInfo = { userProfile: resSearchUser.body } if (resSearchUser.status && resSearchUser.body) {
searchResults.value.push(targetUserInfo) let targetUserInfo = { userProfile: resSearchUser.body }
searchResults.value.push(targetUserInfo)
}
} }
} },
500,
true
)
//
const handleEnterPress = async () => {
debouncedSearch()
} }
// //

View File

@ -221,6 +221,7 @@ import { computed, onMounted, ref } from 'vue'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import { setDocumentDirection } from '@/locales/i18n' import { setDocumentDirection } from '@/locales/i18n'
import { showError, showSuccess } from '@/utils/toast.js' import { showError, showSuccess } from '@/utils/toast.js'
import { useDebounce } from '@/utils/useDebounce'
import { searchUser } from '@/api/userInfo' import { searchUser } from '@/api/userInfo'
import { import {
@ -277,19 +278,28 @@ const handleInputChange = () => {
} }
} }
// //
const handleEnterPress = async () => { const debouncedSearch = useDebounce(
console.log('搜索用户id', searchQuery.value) async () => {
searchResults.value = [] console.log('搜索用户id', searchQuery.value)
selectedUser.value = {} searchResults.value = []
disInvite.value = true selectedUser.value = {}
if (searchQuery.value.trim()) { disInvite.value = true
const resSearchUser = await searchUser(searchQuery.value) if (searchQuery.value.trim()) {
if (resSearchUser.status && resSearchUser.body) { const resSearchUser = await searchUser(searchQuery.value)
let targetUserInfo = { userProfile: resSearchUser.body } if (resSearchUser.status && resSearchUser.body) {
searchResults.value.push(targetUserInfo) let targetUserInfo = { userProfile: resSearchUser.body }
searchResults.value.push(targetUserInfo)
}
} }
} },
500,
true
)
//
const handleEnterPress = async () => {
debouncedSearch()
} }
// //