Vue 3 使用异步 json 设置响应式获取
Posted
技术标签:
【中文标题】Vue 3 使用异步 json 设置响应式获取【英文标题】:Vue 3 setup reactive fetch with async json 【发布时间】:2021-02-07 08:46:38 【问题描述】:我已经安装了 Vue 3,并希望使用从 JSON API 获取的数据来填充反应式对象。
我的组件如下所示。我没有收到任何错误,但我也没有得到任何结果。
<template>
<div>
state.test.total
</div>
</template>
<script>
import reactive from "vue";
export default
setup()
const state = reactive(
test: null,
);
state.test = async () =>
return await fetch("https://api.npms.io/v2/search?q=vue");
;
return
state,
;
,
;
</script>
我希望在屏幕上显示一个数字,因为那是 JSON 文件中 total
中的内容。
开启state.test
如果我只输出state.test
,我会得到下面的输出。
function () var self = this, args = arguments; return new Promise(function (resolve, reject) var gen = fn.apply(self, args); function _next(value) asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); 函数_throw(err) asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); _next(undefined); );
知道如何绕过它吗?
【问题讨论】:
【参考方案1】:当你这样做时:
a = async function test()
您正在为您的状态分配一个功能。但如果你这样做了
a = (async function test()
)();
您仍在为a
分配一个承诺,而不是一个值。如果你想分配一个值,你需要解决这个承诺:
funcResult = await a;
您的 setup 函数不适合在组件的生命周期内执行代码。您可以将 setup 函数视为组件的工厂。因此 setup 函数应该始终是同步的(没有 async 关键字),否则 vue 在 setup 解析时将不知道它应该显示什么。幸运的是,您可以在组合 API 中使用钩子:
import onMounted, reactive from "vue";
export default
setup()
const state = reactive(
test: null,
);
onMounted(async () =>
const response = await fetch("https://api.npms.io/v2/search?q=vue");
state.test = await response.json();
);
return
state,
;
,
;
编辑
考虑到@boussadjra-brahim 的回答,您实际上可以定义异步设置函数,但前提是您使用<Suspense>
包装您的组件。所以你可以选择这个或那个变体。
【讨论】:
经过一些修改后工作正常。你在 onMounted 结束时切换了);
。我忘了在提取的末尾添加.then((response) => response.json());
。非常感谢!
+1 "您可以将 setup 函数视为组件的工厂。因此 setup 函数应该始终是同步的",有用的建议。
@matt 你们如何看待下面的async setup()
解决方案?这是好的还是不好的做法?
@JensTörnell 这种情况没有必要。 setup
函数不需要等待。您可以做一些返回承诺的事情并使用.then()
来填充反应变量。对于加载指示器等更高级的内容,您可以使用Suspense
组件。
@JensTörnell 我已经发布了答案。【参考方案2】:
您应该将async
添加到设置选项,将await
添加到获取功能,并通过Suspense
组件包装您的模板内容:
<template>
<Suspense>
<div>
state.test.total
</div>
</Suspense>
</template>
<script>
import reactive from "vue";
export default
async setup()
const state = reactive(
test: null,
);
try
state.test = await fetch("https://api.npms.io/v2/search?q=vue");
catch (err)
console.error(err)
return
state,
;
,
;
【讨论】:
【参考方案3】:我认为最好不要wait
。
示例:
<template>
<div>
state
</div>
</template>
<script>
import ref from 'vue';
export default
setup()
const state = ref();
fetch('https://api.npms.io/v2/search?q=vue')
.then(response => response.json())
.then(data => state.value = data);
return state ;
,
;
</script>
【讨论】:
这个用例接受了三个建议的解决方案,例如,如果组件是像表格或列表这样的数据显示,当我们可以添加加载指示器然后显示数据时,我的解决方案可能很有用,但它会如果组件包含另一个依赖逻辑,那就不好了 @BoussadjraBrahim 是的,我想Suspense
对此很有用。我没有足够的经验来知道组合函数是否应该是异步的。
感谢您的链接,它们应该是异步的,并且负责在网格中获取和显示数据的独特逻辑,让我们举一个可能包含搜索输入、网格和分页组件,悬念应该只包裹可以异步加载的部分,即网格。以上是关于Vue 3 使用异步 json 设置响应式获取的主要内容,如果未能解决你的问题,请参考以下文章