从可组合访问 ref 值

Posted

技术标签:

【中文标题】从可组合访问 ref 值【英文标题】:Accessing ref values from composable 【发布时间】:2022-01-08 02:17:24 【问题描述】:

这是我的 Vue3 应用代码:

<template>
   names_data 
</template>

<script>
import getData from "./composables/getData"

export default 
  name: "App",
  setup() 
    var filenames = ["test1.json", "test2.json"];
    const  names_data, error, load_data  = getData(
      filenames
    );
    load_data();
    console.log("names", names_data)

    console.log("error", error)

    return  names_data ;
  ,
;
</script>

导入的可组合函数如下:

import  ref  from "@vue/runtime-core";

const getData = (filenames) => 
  const names_data = ref([])
  const error = ref(null)

  const load_data = async () => 
    try 
      var promises = [];
      for (let i = 0; i < filenames.length; i++) 
        var filename = filenames[i]
        promises.push(
          fetch(`data/$filename`).then(
            (res) => (res.ok && res.json()) || Promise.reject(res)
          )
        );
      
      const data = await Promise.all(promises);
      names_data.value = data
     catch (err) 
      error.value = err.message;
      console.log(error.value);
    
  ;
  return  names_data, error, load_data 
;

export default getData

数据文件包含以下内容:

test1.json


  "members": 
    "0": "Alice",
    "1": "Bob",
    "2": "Charlie"
  

test2.json


  "members": 
    "0": "David",
    "1": "Elizabeth",
    "2": "Fred"
  

这一切都有效:我可以从屏幕上显示的模板中看到names_data。但是在控制台中,names_data 显示如下:

RefImpl _shallow: false, dep: undefined, __v_isRef: true, _rawValue: Array(0), _value: Proxy dep:设置(1)ReactiveEffect __v_isRef: 真 _rawValue: (2) […, …] _浅:假 _value: 代理 0: …, 1: … 价值: (...) [[原型]]:对象

我希望能够访问names_data 中的值以进行进一步处理,例如将它们放入表中,但是当我在应用程序中执行console.log(names_data.value) 时,我会得到一个空数组的代理对象。 我认为names_data 对象会以某种方式失去反应性,因为在调用load_data() 时它不会更新。但它显然在模板中是被动的。所以我对这里发生的事情感到困惑。

如何访问 ref 的值以进一步处理它?

【问题讨论】:

【参考方案1】:

对 Estus Flask 接受的答案的后续回答:

如果我将names_data 设为字典而不是列表,即通过这样做

...
names_data = ref()
...
...
    const data = await Promise.all(promises);
    for (let ind=0; ind<data.length; ind++) 
      let filename = filenames[ind]
      names_data.value[filename] = data[ind]
    
...

然后watch() 不再有效。它必须在setup() 中替换为watchEffect(),如下所示:

    watchEffect(() => 
      console.log("updated data", names_data.value)
    )

【讨论】:

【参考方案2】:

它按预期工作。如果不使用反应性,这将导致this 流行的竞争条件。使用反应性的要点是值是反应性的,可以通过组合 API 在其他地方组合。

在这种情况下,无需等待 load_datasetup 正文中完成。它应该在值可用时访问:

const  names_data, error, load_data  = getData(...);
load_data();
watch(names_data, data => 
    console.log(data);
);

【讨论】:

谢谢。我是 Vue 和 javascript 的新手,所以这个链接很有帮助。 我这里有一个后续问题:***.com/questions/70247984/…

以上是关于从可组合访问 ref 值的主要内容,如果未能解决你的问题,请参考以下文章

访问:如果从组合框中选择了以“(REF)”开头的值,则勾选表单上的复选框

访问 isnull 组合值

在 vue api 组合中,我应该在反应性中使用 ref 吗?

返回未绑定访问组合框的先前值

将整数映射到组合框中的自定义类的字符串

从 onclick 事件访问组合框中的选定值