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

Nuxt3中onMounted异步操作问题:repositories ref未更新

问题:repositories ref 值始终无法更新

我遇到了一个问题:repositories ref的值始终无法更新。我已使用async/await,但似乎不起作用,repositories始终是空数组。我可以在onMounted外部正常调用该API,所以我认为问题出在onMounted的使用上,对此我不太了解。

Star.vue 代码

<template>
  <div>
    <h1>Starred Repositories</h1>
    <ul>
      <li v-for="repository in repositories" :key="repository.id">
        <h3>{{ repository.name }}</h3>
        <p>{{ repository.description }}</p>
      </li>
    </ul>
    <button @click="nextPage" :disabled="isLastPage">Next Page</button>
  </div>
</template>

<script setup>
import { Octokit } from '@octokit/core';

const repositories = ref([]);
const page = ref("1")
const runtimeConfig = useRuntimeConfig();

const octokit = new Octokit({
  auth: runtimeConfig.githubToken,
});

const nextPage = () => {
  page.value++;
}

onMounted(async () => {
  const response = await octokit.request('GET /user/starred?page=' + page.value, {
    headers: {
      'X-GitHub-Api-Version': '2022-11-28',
    },
  });
  repositories.value = response.data;
})

console.log(repositories.value);
</script>

App.vue 代码

<script>
import Star from './components/Star.vue'

export default {
  components: {
    Star,
    }
}
</script>

<template>
  <Star />
</template>

解决方案

1. 补全Vue核心API导入

在<script setup>中,ref和onMounted属于Vue的核心API,必须显式导入才能使用。你的代码漏掉了这一步,导致onMounted函数根本没执行,API请求从未发起。添加导入语句:

import { ref, onMounted } from 'vue';

2. 修正异步代码的console.log时机

你在onMounted外部直接打印repositories.value,此时异步请求还未完成,所以输出的是空数组。要验证数据更新,需将打印语句放在请求完成后:

onMounted(async () => {
  const response = await octokit.request('GET /user/starred?page=' + page.value, {
    headers: {
      'X-GitHub-Api-Version': '2022-11-28',
    },
  });
  repositories.value = response.data;
  console.log(repositories.value); // 这里才能看到更新后的数据
})

3. 修复page变量的类型错误

你将page定义为字符串类型ref("1"),执行page.value++时会变成"11"而非数字2,导致后续请求的页码参数错误。改为数字类型初始化:

const page = ref(1);

4. 补充isLastPage变量定义

模板中绑定的isLastPage未定义,会触发控制台警告。可以通过GitHub API返回的Link响应头判断是否还有下一页:

const isLastPage = ref(false);

onMounted(async () => {
  const response = await octokit.request('GET /user/starred?page=' + page.value, {
    headers: {
      'X-GitHub-Api-Version': '2022-11-28',
    },
  });
  repositories.value = response.data;
  // 判断是否为最后一页
  const linkHeader = response.headers.link;
  isLastPage.value = !linkHeader || !linkHeader.includes('rel="next"');
})

修改后的完整Star.vue代码

<template>
  <div>
    <h1>Starred Repositories</h1>
    <ul>
      <li v-for="repository in repositories" :key="repository.id">
        <h3>{{ repository.name }}</h3>
        <p>{{ repository.description }}</p>
      </li>
    </ul>
    <button @click="nextPage" :disabled="isLastPage">Next Page</button>
  </div>
</template>

<script setup>
import { ref, onMounted } from 'vue';
import { Octokit } from '@octokit/core';

const repositories = ref([]);
const page = ref(1);
const isLastPage = ref(false);
const runtimeConfig = useRuntimeConfig();

const octokit = new Octokit({
  auth: runtimeConfig.githubToken,
});

// 封装请求逻辑,方便复用
const fetchStarredRepos = async () => {
  const response = await octokit.request(`GET /user/starred?page=${page.value}`, {
    headers: {
      'X-GitHub-Api-Version': '2022-11-28',
    },
  });
  repositories.value = response.data;
  const linkHeader = response.headers.link;
  isLastPage.value = !linkHeader || !linkHeader.includes('rel="next"');
}

const nextPage = async () => {
  page.value++;
  await fetchStarredRepos(); // 点击下一页时重新请求数据
}

onMounted(async () => {
  await fetchStarredRepos();
})
</script>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 14:02:52