You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 03:05:40