从可组合项访问 ref 值
Accessing ref values from composable
这是我的 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: Set(1) {ReactiveEffect}
__v_isRef: true
_rawValue: (2) [{…}, {…}]
_shallow: false
_value: Proxy {0: {…}, 1: {…}}
value: (...)
[[Prototype]]: Object
我希望能够访问 names_data
中的值以进行进一步处理,例如将它们放入 table,但是当我在应用程序中执行 console.log(names_data.value)
时,我得到了代理对象到一个空数组。
我认为 names_data
对象以某种方式失去了反应性,因为在调用 load_data()
时它没有更新。但它显然在模板中是反应性的。所以我对这里发生的事情感到困惑。
如何访问 ref 的值以进一步处理它?
它按预期工作。如果不使用反应性,这将导致 this 流行的竞争条件。使用反应性的要点是值是反应性的,可以通过组合在其他地方组合API.
在这种情况下,不必等待 load_data
在 setup
主体中完成。它应该在值可用时访问:
const { names_data, error, load_data } = getData(...);
load_data();
watch(names_data, data => {
console.log(data);
});
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)
})
这是我的 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: Set(1) {ReactiveEffect} __v_isRef: true _rawValue: (2) [{…}, {…}] _shallow: false _value: Proxy {0: {…}, 1: {…}} value: (...) [[Prototype]]: Object
我希望能够访问 names_data
中的值以进行进一步处理,例如将它们放入 table,但是当我在应用程序中执行 console.log(names_data.value)
时,我得到了代理对象到一个空数组。
我认为 names_data
对象以某种方式失去了反应性,因为在调用 load_data()
时它没有更新。但它显然在模板中是反应性的。所以我对这里发生的事情感到困惑。
如何访问 ref 的值以进一步处理它?
它按预期工作。如果不使用反应性,这将导致 this 流行的竞争条件。使用反应性的要点是值是反应性的,可以通过组合在其他地方组合API.
在这种情况下,不必等待 load_data
在 setup
主体中完成。它应该在值可用时访问:
const { names_data, error, load_data } = getData(...);
load_data();
watch(names_data, data => {
console.log(data);
});
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)
})