Nuxt3中如何避免修改body时自动触发useFetch执行
问题:Nuxt useFetch 如何仅在点击登录按钮时发送请求,避免输入时自动触发
场景需求
- 登录页面仅在用户点击登录按钮时,向服务器发送POST请求
- 用户修改账号/密码输入框内容时,禁止触发任何请求
现有代码
脚本部分
const body = ref<{ identifier: string, password: string }>({ identifier: '', password: '' }); const {data, execute, error, pending} = await useFetch(`${config.public.baseUrl}/api/auth/local`, { body, lazy: true, method: 'post', immediate: false, watch: [], }) async function login() { console.log("login"); await execute(); }
模板部分
<form @submit.prevent="login"> <label for="email"> Email <input type="text" v-model="body.identifier"> </label> <label for="password"> Password <input type="password" v-model="body.password"> </label> <button>Login</button> </form>
问题现象
未点击登录按钮时,用户在输入框输入内容,/api/auth/local 会被自动发送POST请求。根据Nuxt官方文档说明:
所有fetch选项都可以传入computed或ref值。当这些值更新时,会自动监听并发起新请求。
尝试过v-model.lazy但无法精确控制请求时机;临时使用双ref中转的方案会产生一次被取消的无效请求,并不理想:
const body = ref<{ identifier: string, password: string }>({ identifier: 'user@ok.com', password: '' }); const loginBody = ref<{ identifier: string, password: string }>({ identifier: '', password: '' }); const {data, execute, error, pending} = await useFetch(`${config.public.baseUrl}/api/auth/local`, { body: loginBody, lazy: true, method: 'post', immediate: false, watch: [], }) async function login() { console.log("login"); loginBody.value = body.value; await execute(); }
解决方案
核心是避免让useFetch监听表单的响应式状态,仅在主动调用execute时传入表单值:
const body = ref<{ identifier: string, password: string }>({ identifier: '', password: '' }); // 初始化时不传响应式body,仅配置基础请求参数 const {data, execute, error, pending} = await useFetch(`${config.public.baseUrl}/api/auth/local`, { lazy: true, method: 'post', immediate: false, watch: [], // 确保不监听任何额外响应式源 }) async function login() { console.log("login"); // 调用execute时动态传入当前表单的最新值 await execute({ body: {...body.value} // 解构避免传递响应式对象 }); }
也可以初始化时传入非响应式空对象,同样在execute时覆盖:
const body = ref<{ identifier: string, password: string }>({ identifier: '', password: '' }); const {data, execute, error, pending} = await useFetch(`${config.public.baseUrl}/api/auth/local`, { body: {}, // 非响应式空对象 lazy: true, method: 'post', immediate: false, watch: [], }) async function login() { await execute({ body: body.value }); }
修改后仅在点击登录按钮时发送请求,输入框内容变化不会触发任何请求,也无无效请求产生。
内容的提问来源于stack exchange,提问作者Daniel
相关产品推荐
相关产品推荐

