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

Nuxt中useFetch路由导航时数据不渲染,刷新才正常的问题

问题原因分析
  • useFetch异步赋值时机错误:通过nuxt-link客户端导航时,useFetch是异步执行的,但你直接同步将tempModels.value?.value.vehicles赋值给models,此时请求还未完成,tempModels.value仍为undefined,导致models始终为空数组。而刷新页面时处于SSR模式,Nuxt会等待useFetch请求完成再渲染页面,因此数据能正常显示。
  • 路由参数未保持响应式:直接解构useRoute().params.brand,未跟踪其响应式变化,客户端导航到不同品牌页面时,useFetch不会重新触发请求。
  • 请求逻辑重复:useFetch和axios.post的请求逻辑完全重复,增加维护成本。
修复方案

关键修复点

  1. 利用useFetch的异步特性,等待请求完成后再赋值给响应式变量
  2. 保持路由参数的响应式,确保参数变化时重新请求数据
  3. 统一请求逻辑,用useFetch适配Nuxt的SSR/CSR场景

修复后的完整代码

<template>
  <section class="container">
    <BreadCrumb />
    <h1 class="title">{{ brand }}</h1>
    <div class="models-container">
      <Model
        v-for="model in models"
        :key="model.model"
        :name="model.model"
        :image="model.image"
        @click="handleClick(model.model)"
      />
    </div>
  </section>
</template>

<script setup>
import issue from "~/utils/Encrypt.util";

const router = useRouter();
const route = useRoute();
// 用computed保持brand的响应式
const brand = computed(() => route.params.brand);

const models = ref([]);
const authToken = useCookie("Authorization-Token");

// 封装统一的请求函数
const fetchVehicles = async (token) => {
  const { data } = await useFetch(`${import.meta.env.VITE_API_BASE_URL}/v1/vehicles/search`, {
    method: "POST",
    body: {
      filters: [
        {
          column_name: "manufacture",
          operand: "IsEqualTo",
          value: brand.value,
        },
        {
          column_name: "is_deleted",
          operand: "IsEqualTo",
          value: 0,
        },
      ],
    },
    headers: {
      "Client-Token": import.meta.env.VITE_API_CLIENT_TOKEN,
      "Authorization-Token": token,
    },
  });
  return data.value?.value.vehicles || [];
};

// 初始化请求逻辑
const initFetch = async () => {
  let token = authToken.value;
  // 无token时先获取并存储
  if (!token) {
    const tokenRes = await issue();
    token = tokenRes["Authorization-Token"];
    authToken.value = token;
  }
  // 等待请求完成后赋值
  models.value = await fetchVehicles(token);
};

// 监听brand变化,切换品牌时重新请求
watch(brand, async () => {
  await initFetch();
});

// 页面加载时执行初始化请求
onMounted(async () => {
  await initFetch();
});

function handleClick(model) {
  router.push(`/vehicles/${brand.value}/${model}`);
}
</script>

<style scoped lang="scss">
.title {
  font-size: 24px;
  text-align: center;
  margin-bottom: 24px;
}

.models-container {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  grid-gap: 1rem;
  justify-content: space-between;
}
</style>

修复说明

  • 响应式路由参数:用computed包裹route.params.brand,确保品牌参数变化时能自动触发重新请求。
  • 异步请求处理:将请求逻辑封装为异步函数,通过await等待请求完成后再更新models,保证视图能获取到有效数据。
  • 统一请求逻辑:无论是否存在token,都使用useFetch发起请求,既适配SSR场景,又避免重复代码。
  • 参数监听:通过watch监听品牌参数变化,实现切换品牌页面时自动刷新数据。

内容的提问来源于stack exchange,提问作者NyF__

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 22:52:34