Vue3中如何通过useFetch获取文章后用article.data.id获取标签?
解决Vueuse useFetch 异步请求顺序问题
你的问题核心是useFetch是异步操作,当你发起标签请求时,文章请求还未完成,article.data.id此时不存在,自然无法正确发起请求。结合Vue 3 Options API和Vueuse 10.x的特性,给你两种可行方案:
方案一:用async/await按顺序发起请求
将getData改为异步方法,先等待文章请求完成,再用返回的文章ID发起标签请求:
<template> <main v-if="article && article.data"> <!-- 增加判断避免渲染报错 --> <h1>{{ article.data.title }}</h1> <i>{{ article.data.date }}</i> <p>{{ article.data.text }}</p> <ul class="tags" v-if="tags && tags.data"> <!-- 循环渲染标签,替换原来的硬编码 --> <li v-for="tag in tags.data" :key="tag.id"> <a href="#">{{ tag.name }}</a> </li> </ul> </main> </template> <script> import { useFetch } from '@vueuse/core' export default { data() { return { article: null, tags: null } }, created() { this.$watch( () => this.$route.params, () => { this.getData() }, { immediate: true } ) }, async methods: { // 改为async方法 async getData() { // 等待文章请求完成 const article = await useFetch(`http://0.0.0.0:8000/api/article/${this.$route.params.slug}`, { refresh: true }).json() // 确保文章ID存在后再发起标签请求 if (article.data?.id) { const tags = await useFetch(`http://0.0.0.0:8000/api/article/tags/${article.data.id}`, { refresh: true }).json() this.tags = tags } this.article = article } } } </script>
方案二:监听文章数据变化触发标签请求
通过watch监听article.data的变化,当文章数据加载完成后自动发起标签请求:
<template> <main v-if="article && article.data"> <h1>{{ article.data.title }}</h1> <i>{{ article.data.date }}</i> <p>{{ article.data.text }}</p> <ul class="tags" v-if="tags && tags.data"> <li v-for="tag in tags.data" :key="tag.id"> <a href="#">{{ tag.name }}</a> </li> </ul> </main> </template> <script> import { useFetch } from '@vueuse/core' export default { data() { return { article: null, tags: null } }, created() { this.$watch( () => this.$route.params, () => { this.getArticle() }, { immediate: true } ) // 监听文章数据变化,触发标签请求 this.$watch( () => this.article?.data, (newArticleData) => { if (newArticleData?.id) { this.getTags(newArticleData.id) } } ) }, methods: { getArticle() { const article = useFetch(`http://0.0.0.0:8000/api/article/${this.$route.params.slug}`, { refresh: true }).json() this.article = article }, getTags(articleId) { const tags = useFetch(`http://0.0.0.0:8000/api/article/tags/${articleId}`, { refresh: true }).json() this.tags = tags } } } </script>
额外优化点
- 模板中增加
v-if判断(如v-if="article && article.data"),避免请求未完成时因article.data不存在导致的渲染报错。 - 标签列表改为用
v-for循环渲染,替换原来的硬编码<li>,符合实际业务逻辑。
内容的提问来源于stack exchange,提问作者user22682091
相关产品推荐
相关产品推荐

