Vue组合式API+Inertia搜索输入防抖 避免页面频繁刷新
解决方案
1. 先搞定页面刷新问题
你的页面刷新大概率是因为搜索框被包裹在<form>标签里,浏览器默认会触发表单提交刷新页面。解决方式二选一:
- 给表单添加
@submit.prevent阻止默认行为 - 直接把搜索框改成独立的input,不用表单包裹
示例代码:
<template> <!-- 方式一:阻止表单默认提交 --> <form @submit.prevent> <input v-model="search" type="text" placeholder="搜索用户"> </form> <!-- 方式二:不使用表单 --> <input v-model="search" type="text" placeholder="搜索用户"> </template>
2. 实现输入防抖,避免频繁请求
直接用watch监听输入会每敲一个字符就发一次请求,需要加防抖逻辑——等用户停止输入一段时间(比如300ms)再发起请求,两种实现方式:
手动写防抖逻辑
import { watch, ref, onUnmounted } from 'vue'; import { Inertia } from '@inertiajs/inertia'; const search = ref(''); let debounceTimer = null; watch(search, (value) => { // 清除上一次的定时器 if (debounceTimer) clearTimeout(debounceTimer); // 延迟300ms执行请求 debounceTimer = setTimeout(() => { Inertia.get('users', { search: value }, { preserveState: true, replace: true } ); }, 300); }); // 组件卸载时清理定时器,避免内存泄漏 onUnmounted(() => { if (debounceTimer) clearTimeout(debounceTimer); });
用Lodash的debounce(更简洁)
先安装依赖:
npm install lodash.debounce
然后在组件中使用:
import { watch, ref, onUnmounted } from 'vue'; import { Inertia } from '@inertiajs/inertia'; import debounce from 'lodash.debounce'; const search = ref(''); // 封装防抖后的请求函数 const fetchUsers = debounce((value) => { Inertia.get('users', { search: value }, { preserveState: true, replace: true } ); }, 300); watch(search, (value) => { fetchUsers(value); }); // 组件卸载时取消未执行的请求 onUnmounted(() => { fetchUsers.cancel(); });
额外确认点
- 你配置的
preserveState: true是正确的,这个参数会保留页面现有状态,不会触发全页面重新渲染 - 后端的
withQueryString()已经正确携带搜索参数,确保分页时搜索条件不会丢失
内容的提问来源于stack exchange,提问作者Vaneath
相关产品推荐
相关产品推荐

