即使这个,Vue.js引用也未定义。$ refs显示它们在那里

时间:2019-01-24 21:14:04

标签: javascript vue.js

我对组件的引用

 <Gmap ref="mapRef">

在安装时我正在执行此操作,只是为了查看对象是否可用

 mounted(){
   let self = this
   console.log(self.$refs) // Shows the mapRef object reference
   console.log(self.$refs.mapRef) // returns undefined ???
 }

self。$ refs显示...

  mapRef: VueComponent {_uid: 207, _isVue: true, $options: {…}, _renderProxy: Proxy, _self: VueComponent, …}

那为什么self。$ refs.mapRef返回未定义? 即使它显然在那里?

6 个答案:

答案 0 :(得分:2)

如果这里的方法都不起作用,则需要确保您的组件不是动态导入的

您还需要避免用v-if包装组件,并在this.$refs.mapRef中使用mounted()

我没有使用Vue Google Maps插件/组件,而是我自己的自定义组件

使用:

import CustomComponent from './CustomComponent ';

export default {
  components: {
    CustomComponent,
  },
  ...
}

代替

export default {
  components: {
    CustomComponent: () => import('./CustomComponent'),
  },
  ...
}

然后在已安装的this.$refs.mapRefsetTimeout()中使用this.$nextTick()

mounted(){
  console.log(this.$refs.mapRef) //works!
}

在停止使用动态导入之前,我尝试的方法仍然无法使用:

我没有像这里提到的答案之一那样用v-if包装

 <div v-if="!isLoading"> 
   <GMap ref="mapRef" />
 </div>

我已经将this.$refs.mapRef放在mounted()中,试图用setTimeout()和2层this.$nextTick()包装。

它仅在热装时有效,在页面刷新时停止工作

mounted(){
  setTimeout(()=>{
    this.$nextTick(()=>{
      this.$nextTick(()=>{
        console.log(this.$refs.mapRef) // returns undefined
      });
    });
  }, 0);
}

在另一个答案中感谢此评论:How to access to a child method from the parent in vue.js

答案 1 :(得分:1)

我在获取对传单地图实例的引用时遇到类似的问题,请尝试等待“ nextTick”

mounted(){
  this.$nextTick(()=>{
    let self = this
    console.log(self.$refs) // Shows the mapRef object reference
    console.log(self.$refs.mapRef) // returns undefined ???
  });
}

有关更多信息,请参阅文档-https://vuejs.org/v2/api/#vm-nextTickhttps://vuejs.org/v2/api/#mounted

答案 2 :(得分:1)

您可以将函数包装在$mapPromise提供的vue2-google-maps方法中,这将确保在运行代码之前完全渲染Map:

let self = this;
self.$refs.mapRef.$mapPromise.then(() => {
    console.log(self.$refs.mapRef);
})

这应该可以解决代码依赖于Google Map才能完全呈现才能运行的任何问题。

*注意:$mapPromise在以前的版本中被命名为$mapCreated

查看文档:{​​{3}}

-

原因,当您查看console.log(self.$refs);时显示的是self.$refs是通过引用传递的。因此,当您查看控制台时,其余数据将在几毫秒内完成加载。 self.$ref.mapRef并没有通过引用传递,因此与运行时一样,它仍然保留undefined

尝试在console.log(self.$refs);之后和console.log(self.$refs.mapRef);之前直接添加断点,您可能会发现数据尚未加载。

答案 3 :(得分:0)

我通过使用v-show而不是v-if解决了这个问题。

我将组件包含在v-if语句中。

 <div v-if="!isLoading"> 
   <GMap ref="mapRef" />
 </div>

我刚刚将其更改为v-show

<div v-show="!isLoading"> 
   <GMap ref="mapRef" />
 </div>

现在该对象在mount()中可用。仍然感到奇怪的是,console.log(this。$ refs)显示它可以作为this。$ refs上的键使用,即使实际上不是这样?那是奇怪的行为。

另一件事是,即使我尝试访问数据加载部分中的this。$ refs.mapRef,也就是数据加载后(即isLoading = false之后),我仍然无法访问它。即使这样,它也应该可用,因为v-if通过了。

因此,v-show通过隐藏div而不是不渲染它解决了它。愚蠢的小解决方法。

答案 4 :(得分:0)

在我的情况下,我将ref和v-for一起使用,我错过了仅在dom中渲染v-for之后才生成ref的事实,并且我使用的v-for具有填充的状态数组属性挂载后几秒钟被调用,并且我试图在填充状态数组之前访问我的ref。

答案 5 :(得分:-1)

您可以按以下方式使用它,尽管我仍然不知道它是否会破坏商业项目的打字稿实现。

(this as any).$refs.mapRef