从可组合访问 ref 值(第 2 部分)
Posted
技术标签:
【中文标题】从可组合访问 ref 值(第 2 部分)【英文标题】:Accessing ref values from composable (part 2) 【发布时间】:2022-01-11 19:25:26 【问题描述】:这是我之前的问题的后续问题: Accessing ref values from composable
这是我的应用代码:
<template>
reversed_names
</template>
<script>
import ref, watchEffect from "@vue/runtime-core";
import getData from "./composables/getData";
import reverseNames from "./composables/reverseNames";
export default
name: "App",
setup()
var filenames = ["test1.json", "test2.json"];
const names_data, error, load_data = getData(filenames);
load_data();
const reversed_names = ref();
watchEffect(() =>
const reversed_names = reverseNames(names_data.value);
console.log("revnames inside watchEffect", reversed_names.value);
);
console.log("revnames outside watchEffect", reversed_names);
return names_data, reversed_names ;
,
;
</script>
这里是reverseNames
函数:
import ref from "@vue/runtime-core";
const reverseNames = (names_data) =>
const reverse_names = ref()
var filenames = Object.keys(names_data)
for (let f in filenames)
var filename = filenames[f]
reverse_names.value[filename] =
var members = names_data[filename]["members"]
for (let n in members)
let name = members[n];
var reverseName = name.split("").reverse().join("");
reverse_names.value[filename][name] = reverseName
return reverse_names
;
export default reverseNames
watchEffect
在那里,因此我可以在从文件加载数据后使用names_data
(请参阅上面的链接问题)。
该代码在调用reverseNames
之前运行良好。
names_data.value
包含以下内容:
"test1.json":
"members":
"0": "Alice",
"1": "Bob",
"2": "Charlie"
,
"test2.json":
"members":
"0": "David",
"1": "Elizabeth",
"2": "Fred"
这是令人困惑的部分:
在watchEffect
函数中,控制台会显示该函数的正确返回字典。
但是,在watchEffect
函数之外,控制台只显示在watchEffect()
调用之前定义的空ref()
。
是setup()
返回并显示在模板中的空字典。
如何让setup()
从watchEffect
内部返回reversed_names
?
【问题讨论】:
【参考方案1】:const reversed_names
外部和内部watchEffect
函数范围是不同的、不相关的变量。 reversed_names
在函数作用域内从父作用域遮蔽另一个。
ref 是一种利用 javascript 对象通过引用而不是值传递的模式。这意味着它是一个 ref 而不是一个值,需要在需要保持反应性并注意它在 Vue 应用程序的上下文中使用的每个地方传递。不应重新分配包含 ref 的变量,而是需要重新分配 value
属性。
reverseNames
不是通用帮助函数,而是特定于 Vue,因此可以接受 ref。 reverse_names
没有很好的用途,因为它没有在任何地方传递,因此不能从使用 ref 模式中受益。可能是:
const reverseNames = (namesDataRef) =>
const reverse_names = // not a ref
var filenames = Object.keys(namesDataRef.value)
reverse_names[filename] =
...
reverse_names[filename][name] = reverseName
namesDataRef.value = reverse_names;
// doesn't need to return anything because it uses refs
和
const reversed_names = ref();
watchEffect(() =>
reverseNames(reversed_names);
console.log("revnames inside watchEffect", reversed_names.value);
);
这是一个反模式。如果reverseNames
使用异步副作用或任何可能触发在reverseNames
调用期间无法跟踪的更改,这将是有意义的,类似于another question。但它是同步的,除了单个 ref 不会影响任何东西,因此没有理由使用响应性。相反,可以将反应性提升给调用者:
const reverseNames = (namesData) =>
const reverse_names = // not a ref
...
return reverse_names
和
const reversed_names = ref();
watchEffect(() =>
reversed_names.value = reverseNames(names_data.value);
console.log("revnames inside watchEffect", reversed_names.value);
);
如果没有副作用 (console.log
),就不需要 watchEffect
,它可以是一个计算的 ref:
const reversed_names = computed(() => reverseNames(names_data.value));
【讨论】:
优秀。再次感谢您提供另一个有用的答案。以上是关于从可组合访问 ref 值(第 2 部分)的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Linq 的 where 条件下从可为空的日期时间中删除时间部分