简体   繁体   English

this.$refs 在 Vue 组件中始终为空或未定义

[英]this.$refs always empty or undefined in Vue component

I am new to Vue and am trying to use $refs to grab some elements in the DOM from a sibling component (for very basic purposes, just to get their heights, etc.), and I'm doing so in a computed.我是 Vue 的新手,我正在尝试使用 $refs 从兄弟组件中获取 DOM 中的一些元素(出于非常基本的目的,只是为了获得它们的高度等),我正在计算中这样做。

No matter what I try, this.$root.$refs either always comes back undefined or as an empty object, and I don't know what I'm doing wrong.无论我尝试什么, this.$root.$refs总是返回未定义或作为空对象,而且我不知道我做错了什么。

In a parent component, I have:在父组件中,我有:

<template>
<ComponentA />
<ComponentB />
</template>

In component AI have:在组件 AI 中有:

<template>
  <div id="user-nav">
   <div ref="nav-container">
    <slot />
   </div>
  </div>
</template>

I just try to see if I can access this in ComponentB by console logging我只是想看看我是否可以通过控制台日志记录在 ComponentB 中访问它

 console.log(this.$root.$refs);

in that component's mounted function.在该组件的已安装功能中。

But I keep getting an empty object.但我一直得到一个空对象。

Can you just not access things across sibling components like this???你能不能像这样跨兄弟组件访问东西???

You might have already solved this, but just to answer this Q:您可能已经解决了这个问题,但只是为了回答这个问题:

I had a similar problem and it seems that this happens because the function is being called before Vue has had time to replace the root DOM with its own version.我遇到了类似的问题,似乎发生这种情况是因为在 Vue 有时间用自己的版本替换根 DOM 之前调用了 function。 What you can do to fix this is to create a mounted life-cycle hook and call the function there.你可以做些什么来解决这个问题是创建一个mounted的生命周期钩子并在那里调用 function。

 const vm = new Vue({ el: '#app', data: { sayHi: 'Ello World', }, mounted: function() { // The hook. Here, Vue has already worked its magic. console.log('YOUR ELEMENT ----> ', this.doSomething()) }, methods: { doSomething: function() { return this.$refs['nav-container'] } } })
 <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script> <div id="app"> <span ref="nav-container">{{ sayHi }}</span> </div>

I found the solution here.我在这里找到了解决方案。

You can do it, the problem you have is that you don't actually have any refs on your parent component.你可以做到,你遇到的问题是你的父组件实际上没有任何参考。

I do not recommend doing this anyway either use vuex, an eventbus or $emit我不建议这样做,无论是使用 vuex、eventbus 还是 $emit

 Vue.component('componentA', { template: '<div><span ref="ref-inside-a">You\'re in A,</span></div>': methods.{ log(){ console.log('Hello from a') } } }) Vue,component('componentB': { props, ['ball']: template, '<div><span>This is B.</span></div>'. mounted() { this.$root.$refs['a'].log() console.log(this.$root:$refs['a'],$refs['ref-inside-a']) } }) new Vue({ el: "#app", mounted() { } })
 <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script> <div id="app"> <component-a ref="a"></component-a> <component-b ref="b"></component-b> </div>

I had the same problem.我有同样的问题。 I was using this.$refs in computed property.我在计算属性中使用this.$refs I just got rid of computed properties and used methods and everything started to work properly because $refs are not reactive as mentioned for example here and here我刚刚摆脱了计算属性和使用的方法,一切都开始正常工作,因为 $refs 不是反应性的,例如这里这里提到的

This might not be an answer to your particular problem but I discovered that another reason for $refs being empty is that the component on which it is defined has not created/mounted yet.这可能不是您特定问题的答案,但我发现$refs为空的另一个原因是定义它的组件尚未创建/安装。 Probably due to the lazy rendering Vue uses.可能是由于 Vue 使用的延迟渲染。

I had a set of tabs, one of which was the one I had a "ref=" in, and if I did not visit that tab then $refs was empty.我有一组选项卡,其中一个是我有一个“ref =”的选项卡,如果我没有访问该选项卡,那么$refs是空的。 But íf I first visited the tab then the ref was set up correctly.但是如果我第一次访问该选项卡,那么 ref 设置正确。

In my specific case the在我的具体情况下

this.$refs 

part referenced to several components.部分引用了几个组件。 Accessing a specific component by reference was possible:可以通过引用访问特定组件:

this.$refs[componentName]

To access a specific field of the component above I had to select the first observable:要访问上面组件的特定字段,我必须 select 第一个可观察的:

this.$refs[componentName][0].someFieldToBeSelected -> this works
this.$refs[componentName].someFieldToBeSelected -> this fails

. .

I had the same problem but the cause was another one:我有同样的问题,但原因是另一个:

I had a v-if condition on the referenced element.我在引用的元素上有一个v-if条件。 So at the time of mounting the element was not rendered because the condition was still false.所以在安装时元素没有被渲染,因为条件仍然是错误的。

After 3 hours of looking for the cause for the problem, it was so obvious.找了3个小时的问题原因,很明显。

<template>
  <sub-component v-if="showCondition" ref="componentName">
    <div>someContent</div>
    <div>someMoreContent</div>
  </sub-component> 
</template>

<script lang="ts">
export default class MyComponent extends Vue {
  private showCondition = false; // set to true after a REST request
  mounted() {
    console.log(this.$refs); // this was empty
  }
}
</script>

This problem can be solved by moving the v-if to an additional template element inside the referenced component.这个问题可以通过将 v-if 移动到引用组件内的附加模板元素来解决。

<template>
  <sub-component ref="componentName">
    <template v-if="showCondition">
      <div>someContent</div>
      <div>someMoreContent</div>
    </template>
  </sub-component>
</template>

<script lang="ts">
export default class MyComponent extends Vue {
  mounted() {
    console.log(this.$refs); // now 'componentName' is available
  }
}
</script>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM