我在创建一个元素的引用并将其存储在一个(非React性)对象中时遇到了麻烦,我这样初始化:
const myObj = {
myRef: ref(null),
...
}
而在模板中我也有类似的情况:
<template>
...
<Comp :ref="(el) => { myObj.myRef = el }"/>
...
</template>
现在,如果我尝试访问myObj.myRef
(安装后),我会得到undefined
.我确信这是由于我缺乏对ref和reactive如何在模板中打开的理解。有人能解释一下我在:ref="..."
中实际使用的值是什么吗?
2条答案
按热度按时间sycxhyv71#
**只有 top-level refs会在模板中自动解包。**对于其他refs(例如您在对象中的refs),您仍然需要使用
.value
。有人能解释一下我在
:ref="..."
中实际使用的值是什么吗?这些是文档:Vue指南-模板参考:功能参考
el
是元素引用或组件示例:该函数接收元素引用作为第一个参数。
在本例中,它是一个组件引用(请参阅我在本答案末尾的注解)。
myObj.myRef
是一个引用,* 不是自动解包 *(因为它不是顶级的)。因此,ref * 本身 * 被覆盖,而不是它的值。如果您想使用这种方法,可以使用myObj.myRef.value = el
设置ref。现在,如果我尝试访问
myObj.myRef
(安装后),我会得到undefined
。我不太确定这里发生了什么,尤其是因为您还没有显示这段代码。
myObj.myRef
应该逐字给予组件示例(当您用引用覆盖ref时)。但是,我怀疑您实际上使用的是.value
(myObj.myRef.value
),它在逻辑上会产生undefined
,因为组件示例默认没有value
属性(如果您愿意,可以公开一个属性)。因为你似乎只是简单地将引用绑定到ref,所以你不需要函数语法。您可以使用以下代码:
请注意,我现在正在 * 绑定 * 它,而不仅仅是传递名称(
:ref
vsref
)。这是必需的,因为它包括属性访问,因此不仅仅是一个名称。然而,我怀疑这是一个简化的例子,还有更多的事情要做。
现在,在评论中,你给出了一个完整的实现,并询问是否可以改进。
(As我之前猜的,比你的问题更详细:你实际上是在访问和保存组件上的一个公开的引用,而不仅仅是保存引用本身。
让我们来看看你想达到什么目的
您似乎希望访问组件内部的模板引用。
您当前的实现通过以下方式实现此目的
defineExpose
),ref
属性,这会将暴露的模板ref保存到另一个ref。以下是我们目前所得到的(考虑到您在评论中链接的实现):
Comp.vue
App.vue
Playground1
这个组件很好,但是通过使用计算引用而不是函数
ref
绑定,可以大大简化父组件。变化:
computed
:您可以使用任何您想要的名称,只要您在模板中使用相同的名称。
msg
的ref
属性从纯引用更改为计算的:这将创建一个计算的ref,其中的值将是组件的暴露ref
inner
(如果存在),否则为null
。这些变化产生如下结果:
Playground2
虽然这实际上是两行 * 长 *(额外的ref和空白行),它是非常 * 简单 *。在
ref
绑定的函数处理程序中,没有改变对象,只有一个计算引用访问暴露的属性。当然,这都是相当主观的。您可能更喜欢函数绑定,或者函数方法,但提取到一个方法。等
请注意,组件的模板引用是组件的 * 组件示例 *:
ref
也可以用于子组件。在这种情况下,引用将是组件示例的引用。我不知道你实际上想达到什么目的,但我觉得这值得一提。
rdlzhqv92#
只有顶级引用在模板中会自动魔术般地展开。
你的ref函数将被调用,并将在挂载时完全替换你的ref。尝试访问
.value
很可能会导致undefined
。如果你想要你描述的行为,你需要
:ref="(el) => { myObj.myRef.value = el }"
。您可以使用绑定语法,正如其他人建议的那样:
:ref="myObj.myRef"
。DOM引用有点棘手,所以我推荐一种替代方法(我个人使用):
reactive
,以便使用更好的东西这将给你给予: