Vue3中如何访问composable返回的ref值进行后续业务处理
问题原因
你遇到的现象不是响应性丢失,是异步函数的执行时序问题:load_data是异步函数,内部的fetch请求属于异步任务,你在setup中调用load_data()之后,JS会立刻执行后续的console.log代码,此时请求还未返回,Promise.all还没执行完成,names_data.value自然还是初始的空数组。
模板能正常渲染是因为Vue模板会自动收集响应式依赖,names_data更新后会触发视图重渲染,因此能正确展示更新后的值。
而你打印看到的RefImpl实例、Proxy对象都是Vue3响应式系统的正常底层表现,不属于异常。
正确访问更新后的值的方案
方案1:使用watch监听响应式变量变化
这是最符合Vue响应式设计的写法,只要names_data更新就会触发回调执行后续逻辑:
// 先从vue引入watch import { watch } from "@vue/runtime-core"; export default { name: "App", setup() { var filenames = ["test1.json", "test2.json"]; const { names_data, error, load_data } = getData(filenames); load_data(); // 新增监听逻辑 watch(names_data, (newVal) => { // newVal就是更新后的值,不需要加.value console.log("更新完成的names_data:", newVal) // 你的后续处理逻辑写在这里 }) return { names_data }; }, };
方案2:等待异步函数执行完成后访问
因为load_data本身是async函数,返回Promise,你可以等待它执行完成后再访问值:
export default { name: "App", setup() { var filenames = ["test1.json", "test2.json"]; const { names_data, error, load_data } = getData(filenames); // 用then等待异步执行完成 load_data().then(() => { console.log("请求完成的names_data:", names_data.value) // 后续处理逻辑 }) return { names_data }; }, };
如果你需要写更多异步逻辑,也可以用async立即执行函数包裹:
;(async () => { await load_data() console.log("请求完成的names_data:", names_data.value) // 后续处理逻辑 })()
补充说明
如果你需要拿到非响应式的原始值做处理,可以使用Vue提供的toRaw方法转换:
import { toRaw } from "@vue/runtime-core"; // 在拿到更新后的值后转换 const rawData = toRaw(names_data.value)
内容的提问来源于stack exchange,提问作者berkelem
相关产品推荐
相关产品推荐

